@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.
Files changed (3) hide show
  1. package/index.js +86 -38
  2. package/index.mjs +87 -39
  3. 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
- for (const ttlConfig of options.ttlPerCoordinate) {
9
- if (ttlConfig.coordinate.includes('.')) {
10
- ttlPerSchemaCoordinate[ttlConfig.coordinate] = ttlConfig.ttl;
11
- }
12
- else {
13
- ttlPerType[ttlConfig.coordinate] = ttlConfig.ttl;
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
- getDocumentStringFromContext: (ctx) => ctx.query,
25
- cache: {
26
- get(responseId) {
27
- return options.cache.get(`response-cache:${responseId}`);
28
- },
29
- async set(responseId, data, entities, ttl) {
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
- for (const ttlConfig of options.ttlPerCoordinate) {
7
- if (ttlConfig.coordinate.includes('.')) {
8
- ttlPerSchemaCoordinate[ttlConfig.coordinate] = ttlConfig.ttl;
9
- }
10
- else {
11
- ttlPerType[ttlConfig.coordinate] = ttlConfig.ttl;
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
- getDocumentStringFromContext: (ctx) => ctx.query,
23
- cache: {
24
- get(responseId) {
25
- return options.cache.get(`response-cache:${responseId}`);
26
- },
27
- async set(responseId, data, entities, ttl) {
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.2.0-alpha-10b27a94c.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": "2.3.3",
11
- "@graphql-mesh/types": "0.77.0-alpha-10b27a94c.0",
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/live-query"
20
+ "directory": "packages/plugins/response-cache"
18
21
  },
19
22
  "license": "MIT",
20
23
  "main": "index.js",