@graphql-mesh/plugin-response-cache 0.104.0-alpha-20250124181238-87366ee8e2a95025d881bdaba556f04d337e8331 → 0.104.0-alpha-20250303152151-d99794163758395e3b9780a2cfdef2a5a39433df
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/index.js +51 -4
- package/esm/index.js +51 -5
- package/package.json +10 -8
- package/typings/index.d.cts +3 -3
- package/typings/index.d.ts +3 -3
package/cjs/index.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.default = useMeshResponseCache;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const cache_control_parser_1 = tslib_1.__importDefault(require("cache-control-parser"));
|
|
4
6
|
const response_cache_1 = require("@envelop/response-cache");
|
|
5
7
|
const cross_helpers_1 = require("@graphql-mesh/cross-helpers");
|
|
6
8
|
const string_interpolation_1 = require("@graphql-mesh/string-interpolation");
|
|
7
9
|
const utils_1 = require("@graphql-tools/utils");
|
|
8
10
|
const plugin_response_cache_1 = require("@graphql-yoga/plugin-response-cache");
|
|
11
|
+
const promise_helpers_1 = require("@whatwg-node/promise-helpers");
|
|
9
12
|
function generateSessionIdFactory(sessionIdDef) {
|
|
10
13
|
if (sessionIdDef == null) {
|
|
11
14
|
return function voidSession() {
|
|
@@ -79,7 +82,7 @@ function getCacheForResponseCache(meshCache) {
|
|
|
79
82
|
const entitiesToRemoveJobs = [];
|
|
80
83
|
for (const { typename, id } of entitiesToRemove) {
|
|
81
84
|
const entryId = `${typename}.${id}`;
|
|
82
|
-
const job = (0,
|
|
85
|
+
const job = (0, promise_helpers_1.handleMaybePromise)(() => meshCache.getKeysByPrefix(`response-cache:${entryId}:`), cacheEntriesToDelete => {
|
|
83
86
|
const jobs = [];
|
|
84
87
|
for (const cacheEntryName of cacheEntriesToDelete) {
|
|
85
88
|
const [, , responseId] = cacheEntryName.split(':');
|
|
@@ -108,10 +111,10 @@ function getCacheForResponseCache(meshCache) {
|
|
|
108
111
|
else if (entitiesToRemoveJobs.length > 0) {
|
|
109
112
|
promiseAllJob = Promise.all(entitiesToRemoveJobs);
|
|
110
113
|
}
|
|
111
|
-
return (0,
|
|
114
|
+
return (0, promise_helpers_1.handleMaybePromise)(() => promiseAllJob, () => {
|
|
112
115
|
const responseIdsToCheckJobs = [];
|
|
113
116
|
for (const responseId of responseIdsToCheck) {
|
|
114
|
-
const job = (0,
|
|
117
|
+
const job = (0, promise_helpers_1.handleMaybePromise)(() => meshCache.getKeysByPrefix(`response-cache:${responseId}:`), cacheEntries => {
|
|
115
118
|
if (cacheEntries.length !== 0) {
|
|
116
119
|
return meshCache.delete(`response-cache:${responseId}`);
|
|
117
120
|
}
|
|
@@ -143,7 +146,11 @@ function useMeshResponseCache(options) {
|
|
|
143
146
|
ttlPerSchemaCoordinate[ttlConfig.coordinate] = ttlConfig.ttl;
|
|
144
147
|
}
|
|
145
148
|
}
|
|
146
|
-
|
|
149
|
+
// Stored TTL by the context
|
|
150
|
+
// To be compared with the calculated one later in `onTtl`
|
|
151
|
+
const ttlByContext = new WeakMap();
|
|
152
|
+
// @ts-expect-error - GatewayPlugin types
|
|
153
|
+
const plugin = (0, plugin_response_cache_1.useResponseCache)({
|
|
147
154
|
includeExtensionMetadata: options.includeExtensionMetadata != null
|
|
148
155
|
? options.includeExtensionMetadata
|
|
149
156
|
: cross_helpers_1.process.env.DEBUG === '1',
|
|
@@ -157,5 +164,45 @@ function useMeshResponseCache(options) {
|
|
|
157
164
|
cache: getCacheForResponseCache(options.cache),
|
|
158
165
|
ttlPerType,
|
|
159
166
|
ttlPerSchemaCoordinate,
|
|
167
|
+
// Checks the TTL stored in the context
|
|
168
|
+
// Compares it to the calculated one
|
|
169
|
+
// Then it takes the lowest value
|
|
170
|
+
onTtl({ ttl, context }) {
|
|
171
|
+
const ttlForThisContext = ttlByContext.get(context);
|
|
172
|
+
if (ttlForThisContext != null && ttlForThisContext < ttl) {
|
|
173
|
+
return ttlForThisContext;
|
|
174
|
+
}
|
|
175
|
+
return ttl;
|
|
176
|
+
},
|
|
160
177
|
});
|
|
178
|
+
// Checks the TTL stored in the context
|
|
179
|
+
// Takes the lowest value
|
|
180
|
+
function checkTtl(context, ttl) {
|
|
181
|
+
const ttlForThisContext = ttlByContext.get(context);
|
|
182
|
+
if (ttlForThisContext == null || ttl < ttlForThisContext) {
|
|
183
|
+
ttlByContext.set(context, ttl);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
plugin.onFetch = function ({ executionRequest, context }) {
|
|
187
|
+
// Only if it is a subgraph request
|
|
188
|
+
if (executionRequest && context) {
|
|
189
|
+
return function onFetchDone({ response }) {
|
|
190
|
+
const cacheControlHeader = response.headers.get('cache-control');
|
|
191
|
+
if (cacheControlHeader != null) {
|
|
192
|
+
const parsedCacheControl = cache_control_parser_1.default.parse(cacheControlHeader);
|
|
193
|
+
if (parsedCacheControl['max-age'] != null) {
|
|
194
|
+
const maxAgeInSeconds = parsedCacheControl['max-age'];
|
|
195
|
+
const maxAgeInMs = maxAgeInSeconds * 1000;
|
|
196
|
+
checkTtl(context, maxAgeInMs);
|
|
197
|
+
}
|
|
198
|
+
if (parsedCacheControl['s-maxage'] != null) {
|
|
199
|
+
const sMaxAgeInSeconds = parsedCacheControl['s-maxage'];
|
|
200
|
+
const sMaxAgeInMs = sMaxAgeInSeconds * 1000;
|
|
201
|
+
checkTtl(context, sMaxAgeInMs);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
return plugin;
|
|
161
208
|
}
|
package/esm/index.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import CacheControlParser from 'cache-control-parser';
|
|
1
2
|
import { defaultBuildResponseCacheKey } from '@envelop/response-cache';
|
|
2
3
|
import { process } from '@graphql-mesh/cross-helpers';
|
|
3
4
|
import { stringInterpolator } from '@graphql-mesh/string-interpolation';
|
|
4
|
-
import { isPromise
|
|
5
|
+
import { isPromise } from '@graphql-tools/utils';
|
|
5
6
|
import { useResponseCache } from '@graphql-yoga/plugin-response-cache';
|
|
7
|
+
import { handleMaybePromise } from '@whatwg-node/promise-helpers';
|
|
6
8
|
function generateSessionIdFactory(sessionIdDef) {
|
|
7
9
|
if (sessionIdDef == null) {
|
|
8
10
|
return function voidSession() {
|
|
@@ -76,7 +78,7 @@ function getCacheForResponseCache(meshCache) {
|
|
|
76
78
|
const entitiesToRemoveJobs = [];
|
|
77
79
|
for (const { typename, id } of entitiesToRemove) {
|
|
78
80
|
const entryId = `${typename}.${id}`;
|
|
79
|
-
const job =
|
|
81
|
+
const job = handleMaybePromise(() => meshCache.getKeysByPrefix(`response-cache:${entryId}:`), cacheEntriesToDelete => {
|
|
80
82
|
const jobs = [];
|
|
81
83
|
for (const cacheEntryName of cacheEntriesToDelete) {
|
|
82
84
|
const [, , responseId] = cacheEntryName.split(':');
|
|
@@ -105,10 +107,10 @@ function getCacheForResponseCache(meshCache) {
|
|
|
105
107
|
else if (entitiesToRemoveJobs.length > 0) {
|
|
106
108
|
promiseAllJob = Promise.all(entitiesToRemoveJobs);
|
|
107
109
|
}
|
|
108
|
-
return
|
|
110
|
+
return handleMaybePromise(() => promiseAllJob, () => {
|
|
109
111
|
const responseIdsToCheckJobs = [];
|
|
110
112
|
for (const responseId of responseIdsToCheck) {
|
|
111
|
-
const job =
|
|
113
|
+
const job = handleMaybePromise(() => meshCache.getKeysByPrefix(`response-cache:${responseId}:`), cacheEntries => {
|
|
112
114
|
if (cacheEntries.length !== 0) {
|
|
113
115
|
return meshCache.delete(`response-cache:${responseId}`);
|
|
114
116
|
}
|
|
@@ -140,7 +142,11 @@ export default function useMeshResponseCache(options) {
|
|
|
140
142
|
ttlPerSchemaCoordinate[ttlConfig.coordinate] = ttlConfig.ttl;
|
|
141
143
|
}
|
|
142
144
|
}
|
|
143
|
-
|
|
145
|
+
// Stored TTL by the context
|
|
146
|
+
// To be compared with the calculated one later in `onTtl`
|
|
147
|
+
const ttlByContext = new WeakMap();
|
|
148
|
+
// @ts-expect-error - GatewayPlugin types
|
|
149
|
+
const plugin = useResponseCache({
|
|
144
150
|
includeExtensionMetadata: options.includeExtensionMetadata != null
|
|
145
151
|
? options.includeExtensionMetadata
|
|
146
152
|
: process.env.DEBUG === '1',
|
|
@@ -154,5 +160,45 @@ export default function useMeshResponseCache(options) {
|
|
|
154
160
|
cache: getCacheForResponseCache(options.cache),
|
|
155
161
|
ttlPerType,
|
|
156
162
|
ttlPerSchemaCoordinate,
|
|
163
|
+
// Checks the TTL stored in the context
|
|
164
|
+
// Compares it to the calculated one
|
|
165
|
+
// Then it takes the lowest value
|
|
166
|
+
onTtl({ ttl, context }) {
|
|
167
|
+
const ttlForThisContext = ttlByContext.get(context);
|
|
168
|
+
if (ttlForThisContext != null && ttlForThisContext < ttl) {
|
|
169
|
+
return ttlForThisContext;
|
|
170
|
+
}
|
|
171
|
+
return ttl;
|
|
172
|
+
},
|
|
157
173
|
});
|
|
174
|
+
// Checks the TTL stored in the context
|
|
175
|
+
// Takes the lowest value
|
|
176
|
+
function checkTtl(context, ttl) {
|
|
177
|
+
const ttlForThisContext = ttlByContext.get(context);
|
|
178
|
+
if (ttlForThisContext == null || ttl < ttlForThisContext) {
|
|
179
|
+
ttlByContext.set(context, ttl);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
plugin.onFetch = function ({ executionRequest, context }) {
|
|
183
|
+
// Only if it is a subgraph request
|
|
184
|
+
if (executionRequest && context) {
|
|
185
|
+
return function onFetchDone({ response }) {
|
|
186
|
+
const cacheControlHeader = response.headers.get('cache-control');
|
|
187
|
+
if (cacheControlHeader != null) {
|
|
188
|
+
const parsedCacheControl = CacheControlParser.parse(cacheControlHeader);
|
|
189
|
+
if (parsedCacheControl['max-age'] != null) {
|
|
190
|
+
const maxAgeInSeconds = parsedCacheControl['max-age'];
|
|
191
|
+
const maxAgeInMs = maxAgeInSeconds * 1000;
|
|
192
|
+
checkTtl(context, maxAgeInMs);
|
|
193
|
+
}
|
|
194
|
+
if (parsedCacheControl['s-maxage'] != null) {
|
|
195
|
+
const sMaxAgeInSeconds = parsedCacheControl['s-maxage'];
|
|
196
|
+
const sMaxAgeInMs = sMaxAgeInSeconds * 1000;
|
|
197
|
+
checkTtl(context, sMaxAgeInMs);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
return plugin;
|
|
158
204
|
}
|
package/package.json
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphql-mesh/plugin-response-cache",
|
|
3
|
-
"version": "0.104.0-alpha-
|
|
3
|
+
"version": "0.104.0-alpha-20250303152151-d99794163758395e3b9780a2cfdef2a5a39433df",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"peerDependencies": {
|
|
6
6
|
"graphql": "*"
|
|
7
7
|
},
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@envelop/core": "^5.
|
|
10
|
-
"@envelop/response-cache": "^
|
|
11
|
-
"@graphql-mesh/cross-helpers": "^0.4.
|
|
9
|
+
"@envelop/core": "^5.1.0",
|
|
10
|
+
"@envelop/response-cache": "^7.0.0",
|
|
11
|
+
"@graphql-mesh/cross-helpers": "^0.4.10",
|
|
12
12
|
"@graphql-mesh/string-interpolation": "0.5.8",
|
|
13
|
-
"@graphql-mesh/types": "0.104.0-alpha-
|
|
14
|
-
"@graphql-mesh/utils": "0.104.0-alpha-
|
|
13
|
+
"@graphql-mesh/types": "0.104.0-alpha-20250303152151-d99794163758395e3b9780a2cfdef2a5a39433df",
|
|
14
|
+
"@graphql-mesh/utils": "0.104.0-alpha-20250303152151-d99794163758395e3b9780a2cfdef2a5a39433df",
|
|
15
15
|
"@graphql-tools/utils": "^10.6.2",
|
|
16
|
-
"@graphql-yoga/plugin-response-cache": "^3.
|
|
17
|
-
"
|
|
16
|
+
"@graphql-yoga/plugin-response-cache": "^3.13.1",
|
|
17
|
+
"@whatwg-node/promise-helpers": "^1.0.0",
|
|
18
|
+
"cache-control-parser": "^2.0.6",
|
|
19
|
+
"graphql-yoga": "^5.12.0",
|
|
18
20
|
"tslib": "^2.4.0"
|
|
19
21
|
},
|
|
20
22
|
"repository": {
|
package/typings/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { GatewayPlugin } from '@graphql-hive/gateway-runtime';
|
|
2
2
|
import type { KeyValueCache, YamlConfig } from '@graphql-mesh/types';
|
|
3
3
|
import type { UseResponseCacheParameter } from '@graphql-yoga/plugin-response-cache';
|
|
4
4
|
export type ResponseCacheConfig = Omit<UseResponseCacheParameter, 'cache'> & {
|
|
@@ -20,11 +20,11 @@ export type ResponseCacheConfig = Omit<UseResponseCacheParameter, 'cache'> & {
|
|
|
20
20
|
* Response cache plugin for GraphQL Mesh
|
|
21
21
|
* @param options
|
|
22
22
|
*/
|
|
23
|
-
export default function useMeshResponseCache(options: ResponseCacheConfig):
|
|
23
|
+
export default function useMeshResponseCache(options: ResponseCacheConfig): GatewayPlugin;
|
|
24
24
|
/**
|
|
25
25
|
* @deprecated Use new configuration format `ResponseCacheConfig`
|
|
26
26
|
* @param options
|
|
27
27
|
*/
|
|
28
28
|
export default function useMeshResponseCache(options: YamlConfig.ResponseCacheConfig & {
|
|
29
29
|
cache: KeyValueCache;
|
|
30
|
-
}):
|
|
30
|
+
}): GatewayPlugin;
|
package/typings/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { GatewayPlugin } from '@graphql-hive/gateway-runtime';
|
|
2
2
|
import type { KeyValueCache, YamlConfig } from '@graphql-mesh/types';
|
|
3
3
|
import type { UseResponseCacheParameter } from '@graphql-yoga/plugin-response-cache';
|
|
4
4
|
export type ResponseCacheConfig = Omit<UseResponseCacheParameter, 'cache'> & {
|
|
@@ -20,11 +20,11 @@ export type ResponseCacheConfig = Omit<UseResponseCacheParameter, 'cache'> & {
|
|
|
20
20
|
* Response cache plugin for GraphQL Mesh
|
|
21
21
|
* @param options
|
|
22
22
|
*/
|
|
23
|
-
export default function useMeshResponseCache(options: ResponseCacheConfig):
|
|
23
|
+
export default function useMeshResponseCache(options: ResponseCacheConfig): GatewayPlugin;
|
|
24
24
|
/**
|
|
25
25
|
* @deprecated Use new configuration format `ResponseCacheConfig`
|
|
26
26
|
* @param options
|
|
27
27
|
*/
|
|
28
28
|
export default function useMeshResponseCache(options: YamlConfig.ResponseCacheConfig & {
|
|
29
29
|
cache: KeyValueCache;
|
|
30
|
-
}):
|
|
30
|
+
}): GatewayPlugin;
|