@graphql-mesh/plugin-response-cache 0.2.0-alpha-10b27a94c.0 → 1.0.0-alpha-c34a7d66e.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/index.js +86 -38
- package/index.mjs +87 -39
- package/package.json +7 -4
package/index.js
CHANGED
|
@@ -1,16 +1,90 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const responseCache = require('@envelop/response-cache');
|
|
4
|
+
const stringInterpolation = require('@graphql-mesh/string-interpolation');
|
|
5
|
+
const crossHelpers = require('@graphql-mesh/cross-helpers');
|
|
6
|
+
const utils = require('@graphql-mesh/utils');
|
|
4
7
|
|
|
8
|
+
function getDocumentString(args) {
|
|
9
|
+
return utils.printWithCache(args.document);
|
|
10
|
+
}
|
|
11
|
+
function generateSessionIdFactory(sessionIdDef) {
|
|
12
|
+
return function session(context) {
|
|
13
|
+
return stringInterpolation.stringInterpolator.parse(sessionIdDef, {
|
|
14
|
+
context,
|
|
15
|
+
env: crossHelpers.process.env,
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function generateEnabledFactory(ifDef) {
|
|
20
|
+
return function enabled(context) {
|
|
21
|
+
// eslint-disable-next-line no-new-func
|
|
22
|
+
return new Function(`return ${ifDef}`)();
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function getBuildResponseCacheKey(cacheKeyDef) {
|
|
26
|
+
return function buildResponseCacheKey(cacheKeyParameters) {
|
|
27
|
+
let cacheKey = stringInterpolation.stringInterpolator.parse(cacheKeyDef, {
|
|
28
|
+
...cacheKeyParameters,
|
|
29
|
+
env: crossHelpers.process.env,
|
|
30
|
+
});
|
|
31
|
+
if (!cacheKey) {
|
|
32
|
+
cacheKey = responseCache.defaultBuildResponseCacheKey(cacheKeyParameters);
|
|
33
|
+
}
|
|
34
|
+
return cacheKey;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function getShouldCacheResult(shouldCacheResultDef) {
|
|
38
|
+
return function shouldCacheResult({ result }) {
|
|
39
|
+
// eslint-disable-next-line no-new-func
|
|
40
|
+
return new Function(`return ${shouldCacheResultDef}`)();
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function getCacheForResponseCache(meshCache) {
|
|
44
|
+
return {
|
|
45
|
+
get(responseId) {
|
|
46
|
+
return meshCache.get(`response-cache:${responseId}`);
|
|
47
|
+
},
|
|
48
|
+
async set(responseId, data, entities, ttl) {
|
|
49
|
+
const ttlConfig = Number.isFinite(ttl) ? { ttl: ttl / 1000 } : undefined;
|
|
50
|
+
await Promise.all([...entities].map(async ({ typename, id }) => {
|
|
51
|
+
const entryId = `${typename}.${id}`;
|
|
52
|
+
await meshCache.set(`response-cache:${entryId}:${responseId}`, {}, ttlConfig);
|
|
53
|
+
await meshCache.set(`response-cache:${responseId}:${entryId}`, {}, ttlConfig);
|
|
54
|
+
}));
|
|
55
|
+
return meshCache.set(`response-cache:${responseId}`, data, ttlConfig);
|
|
56
|
+
},
|
|
57
|
+
async invalidate(entitiesToRemove) {
|
|
58
|
+
const responseIdsToCheck = new Set();
|
|
59
|
+
await Promise.all([...entitiesToRemove].map(async ({ typename, id }) => {
|
|
60
|
+
const entryId = `${typename}.${id}`;
|
|
61
|
+
const cacheEntriesToDelete = await meshCache.getKeysByPrefix(`response-cache:${entryId}:`);
|
|
62
|
+
await Promise.all(cacheEntriesToDelete.map(cacheEntryName => {
|
|
63
|
+
const [, , responseId] = cacheEntryName.split(':');
|
|
64
|
+
responseIdsToCheck.add(responseId);
|
|
65
|
+
return meshCache.delete(entryId);
|
|
66
|
+
}));
|
|
67
|
+
}));
|
|
68
|
+
await Promise.all([...responseIdsToCheck].map(async (responseId) => {
|
|
69
|
+
const cacheEntries = await meshCache.getKeysByPrefix(`response-cache:${responseId}:`);
|
|
70
|
+
if (cacheEntries.length === 0) {
|
|
71
|
+
await meshCache.delete(`response-cache:${responseId}`);
|
|
72
|
+
}
|
|
73
|
+
}));
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
5
77
|
function useMeshResponseCache(options) {
|
|
6
78
|
const ttlPerType = {};
|
|
7
79
|
const ttlPerSchemaCoordinate = {};
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
80
|
+
if (options.ttlPerCoordinate) {
|
|
81
|
+
for (const ttlConfig of options.ttlPerCoordinate) {
|
|
82
|
+
if (ttlConfig.coordinate.includes('.')) {
|
|
83
|
+
ttlPerSchemaCoordinate[ttlConfig.coordinate] = ttlConfig.ttl;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
ttlPerType[ttlConfig.coordinate] = ttlConfig.ttl;
|
|
87
|
+
}
|
|
14
88
|
}
|
|
15
89
|
}
|
|
16
90
|
return responseCache.useResponseCache({
|
|
@@ -21,38 +95,12 @@ function useMeshResponseCache(options) {
|
|
|
21
95
|
includeExtensionMetadata: options.includeExtensionMetadata,
|
|
22
96
|
ttlPerType,
|
|
23
97
|
ttlPerSchemaCoordinate,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
await Promise.all([...entities].map(async ({ typename, id }) => {
|
|
31
|
-
const entryId = `${typename}.${id}`;
|
|
32
|
-
await options.cache.set(`response-cache:${entryId}:${responseId}`, {}, { ttl: ttl / 1000 });
|
|
33
|
-
await options.cache.set(`response-cache:${responseId}:${entryId}`, {}, { ttl: ttl / 1000 });
|
|
34
|
-
}));
|
|
35
|
-
return options.cache.set(`response-cache:${responseId}`, data, { ttl: ttl / 1000 });
|
|
36
|
-
},
|
|
37
|
-
async invalidate(entitiesToRemove) {
|
|
38
|
-
const responseIdsToCheck = new Set();
|
|
39
|
-
await Promise.all([...entitiesToRemove].map(async ({ typename, id }) => {
|
|
40
|
-
const entryId = `${typename}.${id}`;
|
|
41
|
-
const cacheEntriesToDelete = await options.cache.getKeysByPrefix(`response-cache:${entryId}:`);
|
|
42
|
-
await Promise.all(cacheEntriesToDelete.map(cacheEntryName => {
|
|
43
|
-
const [, , responseId] = cacheEntryName.split(':');
|
|
44
|
-
responseIdsToCheck.add(responseId);
|
|
45
|
-
return options.cache.delete(entryId);
|
|
46
|
-
}));
|
|
47
|
-
}));
|
|
48
|
-
await Promise.all([...responseIdsToCheck].map(async (responseId) => {
|
|
49
|
-
const cacheEntries = await options.cache.getKeysByPrefix(`response-cache:${responseId}:`);
|
|
50
|
-
if (cacheEntries.length === 0) {
|
|
51
|
-
await options.cache.delete(`response-cache:${responseId}`);
|
|
52
|
-
}
|
|
53
|
-
}));
|
|
54
|
-
},
|
|
55
|
-
},
|
|
98
|
+
getDocumentString,
|
|
99
|
+
session: options.sessionId ? generateSessionIdFactory(options.sessionId) : undefined,
|
|
100
|
+
enabled: options.if ? generateEnabledFactory(options.if) : undefined,
|
|
101
|
+
buildResponseCacheKey: options.cacheKey ? getBuildResponseCacheKey(options.cacheKey) : undefined,
|
|
102
|
+
shouldCacheResult: options.shouldCacheResult ? getShouldCacheResult(options.shouldCacheResult) : undefined,
|
|
103
|
+
cache: getCacheForResponseCache(options.cache),
|
|
56
104
|
});
|
|
57
105
|
}
|
|
58
106
|
|
package/index.mjs
CHANGED
|
@@ -1,14 +1,88 @@
|
|
|
1
|
-
import { useResponseCache } from '@envelop/response-cache';
|
|
1
|
+
import { useResponseCache, defaultBuildResponseCacheKey } from '@envelop/response-cache';
|
|
2
|
+
import { stringInterpolator } from '@graphql-mesh/string-interpolation';
|
|
3
|
+
import { process } from '@graphql-mesh/cross-helpers';
|
|
4
|
+
import { printWithCache } from '@graphql-mesh/utils';
|
|
2
5
|
|
|
6
|
+
function getDocumentString(args) {
|
|
7
|
+
return printWithCache(args.document);
|
|
8
|
+
}
|
|
9
|
+
function generateSessionIdFactory(sessionIdDef) {
|
|
10
|
+
return function session(context) {
|
|
11
|
+
return stringInterpolator.parse(sessionIdDef, {
|
|
12
|
+
context,
|
|
13
|
+
env: process.env,
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function generateEnabledFactory(ifDef) {
|
|
18
|
+
return function enabled(context) {
|
|
19
|
+
// eslint-disable-next-line no-new-func
|
|
20
|
+
return new Function(`return ${ifDef}`)();
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function getBuildResponseCacheKey(cacheKeyDef) {
|
|
24
|
+
return function buildResponseCacheKey(cacheKeyParameters) {
|
|
25
|
+
let cacheKey = stringInterpolator.parse(cacheKeyDef, {
|
|
26
|
+
...cacheKeyParameters,
|
|
27
|
+
env: process.env,
|
|
28
|
+
});
|
|
29
|
+
if (!cacheKey) {
|
|
30
|
+
cacheKey = defaultBuildResponseCacheKey(cacheKeyParameters);
|
|
31
|
+
}
|
|
32
|
+
return cacheKey;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function getShouldCacheResult(shouldCacheResultDef) {
|
|
36
|
+
return function shouldCacheResult({ result }) {
|
|
37
|
+
// eslint-disable-next-line no-new-func
|
|
38
|
+
return new Function(`return ${shouldCacheResultDef}`)();
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function getCacheForResponseCache(meshCache) {
|
|
42
|
+
return {
|
|
43
|
+
get(responseId) {
|
|
44
|
+
return meshCache.get(`response-cache:${responseId}`);
|
|
45
|
+
},
|
|
46
|
+
async set(responseId, data, entities, ttl) {
|
|
47
|
+
const ttlConfig = Number.isFinite(ttl) ? { ttl: ttl / 1000 } : undefined;
|
|
48
|
+
await Promise.all([...entities].map(async ({ typename, id }) => {
|
|
49
|
+
const entryId = `${typename}.${id}`;
|
|
50
|
+
await meshCache.set(`response-cache:${entryId}:${responseId}`, {}, ttlConfig);
|
|
51
|
+
await meshCache.set(`response-cache:${responseId}:${entryId}`, {}, ttlConfig);
|
|
52
|
+
}));
|
|
53
|
+
return meshCache.set(`response-cache:${responseId}`, data, ttlConfig);
|
|
54
|
+
},
|
|
55
|
+
async invalidate(entitiesToRemove) {
|
|
56
|
+
const responseIdsToCheck = new Set();
|
|
57
|
+
await Promise.all([...entitiesToRemove].map(async ({ typename, id }) => {
|
|
58
|
+
const entryId = `${typename}.${id}`;
|
|
59
|
+
const cacheEntriesToDelete = await meshCache.getKeysByPrefix(`response-cache:${entryId}:`);
|
|
60
|
+
await Promise.all(cacheEntriesToDelete.map(cacheEntryName => {
|
|
61
|
+
const [, , responseId] = cacheEntryName.split(':');
|
|
62
|
+
responseIdsToCheck.add(responseId);
|
|
63
|
+
return meshCache.delete(entryId);
|
|
64
|
+
}));
|
|
65
|
+
}));
|
|
66
|
+
await Promise.all([...responseIdsToCheck].map(async (responseId) => {
|
|
67
|
+
const cacheEntries = await meshCache.getKeysByPrefix(`response-cache:${responseId}:`);
|
|
68
|
+
if (cacheEntries.length === 0) {
|
|
69
|
+
await meshCache.delete(`response-cache:${responseId}`);
|
|
70
|
+
}
|
|
71
|
+
}));
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
3
75
|
function useMeshResponseCache(options) {
|
|
4
76
|
const ttlPerType = {};
|
|
5
77
|
const ttlPerSchemaCoordinate = {};
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
78
|
+
if (options.ttlPerCoordinate) {
|
|
79
|
+
for (const ttlConfig of options.ttlPerCoordinate) {
|
|
80
|
+
if (ttlConfig.coordinate.includes('.')) {
|
|
81
|
+
ttlPerSchemaCoordinate[ttlConfig.coordinate] = ttlConfig.ttl;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
ttlPerType[ttlConfig.coordinate] = ttlConfig.ttl;
|
|
85
|
+
}
|
|
12
86
|
}
|
|
13
87
|
}
|
|
14
88
|
return useResponseCache({
|
|
@@ -19,38 +93,12 @@ function useMeshResponseCache(options) {
|
|
|
19
93
|
includeExtensionMetadata: options.includeExtensionMetadata,
|
|
20
94
|
ttlPerType,
|
|
21
95
|
ttlPerSchemaCoordinate,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
await Promise.all([...entities].map(async ({ typename, id }) => {
|
|
29
|
-
const entryId = `${typename}.${id}`;
|
|
30
|
-
await options.cache.set(`response-cache:${entryId}:${responseId}`, {}, { ttl: ttl / 1000 });
|
|
31
|
-
await options.cache.set(`response-cache:${responseId}:${entryId}`, {}, { ttl: ttl / 1000 });
|
|
32
|
-
}));
|
|
33
|
-
return options.cache.set(`response-cache:${responseId}`, data, { ttl: ttl / 1000 });
|
|
34
|
-
},
|
|
35
|
-
async invalidate(entitiesToRemove) {
|
|
36
|
-
const responseIdsToCheck = new Set();
|
|
37
|
-
await Promise.all([...entitiesToRemove].map(async ({ typename, id }) => {
|
|
38
|
-
const entryId = `${typename}.${id}`;
|
|
39
|
-
const cacheEntriesToDelete = await options.cache.getKeysByPrefix(`response-cache:${entryId}:`);
|
|
40
|
-
await Promise.all(cacheEntriesToDelete.map(cacheEntryName => {
|
|
41
|
-
const [, , responseId] = cacheEntryName.split(':');
|
|
42
|
-
responseIdsToCheck.add(responseId);
|
|
43
|
-
return options.cache.delete(entryId);
|
|
44
|
-
}));
|
|
45
|
-
}));
|
|
46
|
-
await Promise.all([...responseIdsToCheck].map(async (responseId) => {
|
|
47
|
-
const cacheEntries = await options.cache.getKeysByPrefix(`response-cache:${responseId}:`);
|
|
48
|
-
if (cacheEntries.length === 0) {
|
|
49
|
-
await options.cache.delete(`response-cache:${responseId}`);
|
|
50
|
-
}
|
|
51
|
-
}));
|
|
52
|
-
},
|
|
53
|
-
},
|
|
96
|
+
getDocumentString,
|
|
97
|
+
session: options.sessionId ? generateSessionIdFactory(options.sessionId) : undefined,
|
|
98
|
+
enabled: options.if ? generateEnabledFactory(options.if) : undefined,
|
|
99
|
+
buildResponseCacheKey: options.cacheKey ? getBuildResponseCacheKey(options.cacheKey) : undefined,
|
|
100
|
+
shouldCacheResult: options.shouldCacheResult ? getShouldCacheResult(options.shouldCacheResult) : undefined,
|
|
101
|
+
cache: getCacheForResponseCache(options.cache),
|
|
54
102
|
});
|
|
55
103
|
}
|
|
56
104
|
|
package/package.json
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphql-mesh/plugin-response-cache",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0-alpha-c34a7d66e.0",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"peerDependencies": {
|
|
6
|
+
"@graphql-mesh/types": "0.79.0-alpha-c34a7d66e.0",
|
|
6
7
|
"graphql": "*"
|
|
7
8
|
},
|
|
8
9
|
"dependencies": {
|
|
9
10
|
"@envelop/core": "^2.3.2",
|
|
10
|
-
"@envelop/response-cache": "
|
|
11
|
-
"@graphql-mesh/
|
|
11
|
+
"@envelop/response-cache": "3.0.0",
|
|
12
|
+
"@graphql-mesh/cross-helpers": "0.2.0",
|
|
13
|
+
"@graphql-mesh/string-interpolation": "0.3.0",
|
|
14
|
+
"@graphql-mesh/utils": "1.0.0-alpha-c34a7d66e.0",
|
|
12
15
|
"tslib": "^2.4.0"
|
|
13
16
|
},
|
|
14
17
|
"repository": {
|
|
15
18
|
"type": "git",
|
|
16
19
|
"url": "Urigo/graphql-mesh",
|
|
17
|
-
"directory": "packages/plugins/
|
|
20
|
+
"directory": "packages/plugins/response-cache"
|
|
18
21
|
},
|
|
19
22
|
"license": "MIT",
|
|
20
23
|
"main": "index.js",
|