slonik-interceptor-query-cache 2.0.1 → 2.1.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/LICENSE +1 -1
- package/README.md +15 -49
- package/dist/src/Logger.d.ts +1 -0
- package/dist/src/Logger.js +7 -0
- package/dist/src/factories/createQueryCacheInterceptor.d.ts +13 -0
- package/dist/src/factories/createQueryCacheInterceptor.js +49 -0
- package/dist/src/factories/index.d.ts +1 -0
- package/dist/src/factories/index.js +5 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +5 -0
- package/dist/src/utilities/extractCacheAttributes.d.ts +3 -0
- package/dist/src/utilities/extractCacheAttributes.js +13 -0
- package/dist/src/utilities/index.d.ts +1 -0
- package/dist/src/utilities/index.js +5 -0
- package/package.json +29 -55
- package/src/Logger.ts +7 -0
- package/{dist/factories/createQueryCacheInterceptor.js.flow → src/factories/createQueryCacheInterceptor.ts} +33 -27
- package/src/{index.js → factories/index.ts} +1 -3
- package/{dist/index.js.flow → src/index.ts} +0 -2
- package/src/utilities/extractCacheAttributes.ts +11 -0
- package/src/utilities/index.ts +3 -0
- package/tsconfig.json +26 -0
- package/.flowconfig +0 -3
- package/dist/Logger.js +0 -17
- package/dist/Logger.js.flow +0 -7
- package/dist/Logger.js.map +0 -1
- package/dist/factories/createQueryCacheInterceptor.js +0 -67
- package/dist/factories/createQueryCacheInterceptor.js.map +0 -1
- package/dist/factories/index.js +0 -16
- package/dist/factories/index.js.flow +0 -3
- package/dist/factories/index.js.map +0 -1
- package/dist/index.js +0 -14
- package/dist/index.js.map +0 -1
- package/dist/utilities/extractCacheAttributes.js +0 -22
- package/dist/utilities/extractCacheAttributes.js.flow +0 -13
- package/dist/utilities/extractCacheAttributes.js.map +0 -1
- package/dist/utilities/index.js +0 -16
- package/dist/utilities/index.js.flow +0 -3
- package/dist/utilities/index.js.map +0 -1
- package/src/Logger.js +0 -7
- package/src/factories/createQueryCacheInterceptor.js +0 -83
- package/src/factories/index.js +0 -3
- package/src/utilities/extractCacheAttributes.js +0 -13
- package/src/utilities/index.js +0 -3
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,49 +1,18 @@
|
|
|
1
1
|
# slonik-interceptor-query-cache
|
|
2
2
|
|
|
3
|
-
[](https://travis-ci.
|
|
3
|
+
[](https://travis-ci.com/github/gajus/slonik-interceptor-query-cache)
|
|
4
4
|
[](https://coveralls.io/github/gajus/slonik-interceptor-query-cache)
|
|
5
5
|
[](https://www.npmjs.org/package/slonik-interceptor-query-cache)
|
|
6
6
|
[](https://github.com/gajus/canonical)
|
|
7
7
|
[](https://twitter.com/kuizinas)
|
|
8
8
|
|
|
9
|
-
Caches [Slonik](https://github.com/gajus/slonik)
|
|
9
|
+
Caches [Slonik](https://github.com/gajus/slonik) query results.
|
|
10
10
|
|
|
11
11
|
## Usage
|
|
12
12
|
|
|
13
13
|
Query cache interceptor is initialised using a custom storage service. The [Example Usage](#example-usage) documentation shows how to create a compatible storage service using [`node-cache`](https://www.npmjs.com/package/node-cache).
|
|
14
14
|
|
|
15
|
-
Which queries are cached is controlled using cache attributes. Cache attributes are comments starting with
|
|
16
|
-
|
|
17
|
-
## API
|
|
18
|
-
|
|
19
|
-
```js
|
|
20
|
-
import {
|
|
21
|
-
createQueryCacheInterceptor
|
|
22
|
-
} from 'slonik-interceptor-query-cache';
|
|
23
|
-
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
```js
|
|
27
|
-
type CacheAttributesType = {|
|
|
28
|
-
+ttl: number,
|
|
29
|
-
|};
|
|
30
|
-
|
|
31
|
-
type StorageType = {|
|
|
32
|
-
+get: (query: QueryType, cacheAttributes: CacheAttributesType) => Promise<QueryResultType<QueryResultRowType> | null>,
|
|
33
|
-
+set: (query: QueryType, cacheAttributes: CacheAttributesType, queryResult: QueryResultType<QueryResultRowType>) => Promise<void>,
|
|
34
|
-
|};
|
|
35
|
-
|
|
36
|
-
type ConfigurationInputType = {|
|
|
37
|
-
+storage: StorageType,
|
|
38
|
-
|};
|
|
39
|
-
|
|
40
|
-
type ConfigurationType = {|
|
|
41
|
-
+storage: StorageType,
|
|
42
|
-
|};
|
|
43
|
-
|
|
44
|
-
(configurationInput: ConfigurationInputType) => InterceptorType;
|
|
45
|
-
|
|
46
|
-
```
|
|
15
|
+
Which queries are cached is controlled using cache attributes. Cache attributes are comments starting with `-- @cache-` prefix. Only queries with cache attributes are cached (see [Cache attributes](#cache-attributes))
|
|
47
16
|
|
|
48
17
|
## Cache attributes
|
|
49
18
|
|
|
@@ -74,21 +43,19 @@ const hashQuery = (query: QueryType): string => {
|
|
|
74
43
|
return JSON.stringify(query);
|
|
75
44
|
};
|
|
76
45
|
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
46
|
+
const pool = await createPool('postgres://', {
|
|
47
|
+
interceptors: [
|
|
48
|
+
createQueryCacheInterceptor({
|
|
49
|
+
storage: {
|
|
50
|
+
get: (query) => {
|
|
51
|
+
return cache.get(hashQuery(query)) || null;
|
|
52
|
+
},
|
|
53
|
+
set: (query, cacheAttributes, queryResult) => {
|
|
54
|
+
cache.set(hashQuery(query), queryResult, cacheAttributes.ttl);
|
|
55
|
+
},
|
|
85
56
|
},
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
];
|
|
89
|
-
|
|
90
|
-
const pool = createPool('postgres://', {
|
|
91
|
-
interceptors
|
|
57
|
+
}),
|
|
58
|
+
]
|
|
92
59
|
});
|
|
93
60
|
|
|
94
61
|
await connection.any(sql`
|
|
@@ -100,5 +67,4 @@ await connection.any(sql`
|
|
|
100
67
|
WHERE
|
|
101
68
|
code_alpha_2 = ${countryCode}
|
|
102
69
|
`);
|
|
103
|
-
|
|
104
70
|
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const Logger: import("roarr").Logger<import("roarr/dist/src/types").JsonObject>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Interceptor, Query, QueryResultRow, QueryResult } from 'slonik';
|
|
2
|
+
declare type CacheAttributes = {
|
|
3
|
+
ttl: number;
|
|
4
|
+
};
|
|
5
|
+
declare type Storage = {
|
|
6
|
+
get: (query: Query, cacheAttributes: CacheAttributes) => Promise<QueryResult<QueryResultRow> | null>;
|
|
7
|
+
set: (query: Query, cacheAttributes: CacheAttributes, queryResult: QueryResult<QueryResultRow>) => Promise<void>;
|
|
8
|
+
};
|
|
9
|
+
declare type ConfigurationInput = {
|
|
10
|
+
storage: Storage;
|
|
11
|
+
};
|
|
12
|
+
export declare const createQueryCacheInterceptor: (configurationInput: ConfigurationInput) => Interceptor;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createQueryCacheInterceptor = void 0;
|
|
4
|
+
const Logger_1 = require("../Logger");
|
|
5
|
+
const utilities_1 = require("../utilities");
|
|
6
|
+
const log = Logger_1.Logger.child({
|
|
7
|
+
namespace: 'createQueryCacheInterceptor',
|
|
8
|
+
});
|
|
9
|
+
const createQueryCacheInterceptor = (configurationInput) => {
|
|
10
|
+
const configuration = {
|
|
11
|
+
...configurationInput,
|
|
12
|
+
};
|
|
13
|
+
return {
|
|
14
|
+
beforeQueryExecution: async (context, query) => {
|
|
15
|
+
var _a;
|
|
16
|
+
const cacheAttributes = (_a = context.sandbox.cache) === null || _a === void 0 ? void 0 : _a.cacheAttributes;
|
|
17
|
+
if (!cacheAttributes) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
const maybeResult = await configuration.storage.get(query, cacheAttributes);
|
|
21
|
+
if (maybeResult) {
|
|
22
|
+
log.info({
|
|
23
|
+
queryId: context.queryId,
|
|
24
|
+
}, 'query is served from cache');
|
|
25
|
+
return maybeResult;
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
},
|
|
29
|
+
beforeQueryResult: async (context, query, result) => {
|
|
30
|
+
var _a;
|
|
31
|
+
const cacheAttributes = (_a = context.sandbox.cache) === null || _a === void 0 ? void 0 : _a.cacheAttributes;
|
|
32
|
+
if (cacheAttributes) {
|
|
33
|
+
await configuration.storage.set(query, cacheAttributes, result);
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
},
|
|
37
|
+
beforeTransformQuery: async (context, query) => {
|
|
38
|
+
const cacheAttributes = (0, utilities_1.extractCacheAttributes)(query.sql);
|
|
39
|
+
if (!cacheAttributes) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
context.sandbox.cache = {
|
|
43
|
+
cacheAttributes,
|
|
44
|
+
};
|
|
45
|
+
return null;
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
exports.createQueryCacheInterceptor = createQueryCacheInterceptor;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createQueryCacheInterceptor, } from './createQueryCacheInterceptor';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createQueryCacheInterceptor = void 0;
|
|
4
|
+
var createQueryCacheInterceptor_1 = require("./createQueryCacheInterceptor");
|
|
5
|
+
Object.defineProperty(exports, "createQueryCacheInterceptor", { enumerable: true, get: function () { return createQueryCacheInterceptor_1.createQueryCacheInterceptor; } });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createQueryCacheInterceptor, } from './factories';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createQueryCacheInterceptor = void 0;
|
|
4
|
+
var factories_1 = require("./factories");
|
|
5
|
+
Object.defineProperty(exports, "createQueryCacheInterceptor", { enumerable: true, get: function () { return factories_1.createQueryCacheInterceptor; } });
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractCacheAttributes = void 0;
|
|
4
|
+
const extractCacheAttributes = (subject) => {
|
|
5
|
+
const matches = /-- @cache-ttl (\d+)/u.exec(subject);
|
|
6
|
+
if (matches) {
|
|
7
|
+
return {
|
|
8
|
+
ttl: Number(matches[1]),
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
return null;
|
|
12
|
+
};
|
|
13
|
+
exports.extractCacheAttributes = extractCacheAttributes;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { extractCacheAttributes, } from './extractCacheAttributes';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractCacheAttributes = void 0;
|
|
4
|
+
var extractCacheAttributes_1 = require("./extractCacheAttributes");
|
|
5
|
+
Object.defineProperty(exports, "extractCacheAttributes", { enumerable: true, get: function () { return extractCacheAttributes_1.extractCacheAttributes; } });
|
package/package.json
CHANGED
|
@@ -5,44 +5,31 @@
|
|
|
5
5
|
"url": "http://gajus.com"
|
|
6
6
|
},
|
|
7
7
|
"ava": {
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
]
|
|
12
|
-
},
|
|
8
|
+
"extensions": [
|
|
9
|
+
"ts"
|
|
10
|
+
],
|
|
13
11
|
"files": [
|
|
14
12
|
"test/slonik-interceptor-query-cache/**/*"
|
|
15
13
|
],
|
|
16
14
|
"require": [
|
|
17
|
-
"
|
|
15
|
+
"ts-node/register/transpile-only"
|
|
18
16
|
]
|
|
19
17
|
},
|
|
20
|
-
"
|
|
21
|
-
"roarr": "^2.15.2",
|
|
22
|
-
"slonik": "^22.4.0"
|
|
23
|
-
},
|
|
24
|
-
"description": "Caches Slonik queries.",
|
|
18
|
+
"description": "Cache Slonik query results.",
|
|
25
19
|
"devDependencies": {
|
|
26
|
-
"@
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"babel-plugin-istanbul": "^6.0.0",
|
|
34
|
-
"babel-plugin-macros": "^2.8.0",
|
|
35
|
-
"babel-plugin-transform-export-default-name": "^2.0.4",
|
|
36
|
-
"coveralls": "^3.0.9",
|
|
37
|
-
"eslint": "^6.8.0",
|
|
38
|
-
"eslint-config-canonical": "^18.1.1",
|
|
39
|
-
"flow-bin": "^0.118.0",
|
|
40
|
-
"flow-copy-source": "^2.0.9",
|
|
41
|
-
"husky": "^4.2.3",
|
|
20
|
+
"@istanbuljs/nyc-config-typescript": "^1.0.2",
|
|
21
|
+
"ava": "^3.15.0",
|
|
22
|
+
"coveralls": "^3.1.1",
|
|
23
|
+
"del-cli": "^4.0.1",
|
|
24
|
+
"eslint": "^8.4.1",
|
|
25
|
+
"eslint-config-canonical": "^32.46.0",
|
|
26
|
+
"husky": "^7.0.4",
|
|
42
27
|
"inline-loops.macro": "^1.2.2",
|
|
43
|
-
"nyc": "^15.
|
|
44
|
-
"semantic-release": "^
|
|
45
|
-
"sinon": "^
|
|
28
|
+
"nyc": "^15.1.0",
|
|
29
|
+
"semantic-release": "^18.0.1",
|
|
30
|
+
"sinon": "^12.0.1",
|
|
31
|
+
"ts-node": "^10.4.0",
|
|
32
|
+
"typescript": "^4.7.4"
|
|
46
33
|
},
|
|
47
34
|
"engines": {
|
|
48
35
|
"node": ">=8.0"
|
|
@@ -55,39 +42,26 @@
|
|
|
55
42
|
"keywords": [
|
|
56
43
|
"postgresql",
|
|
57
44
|
"interceptor",
|
|
58
|
-
"
|
|
45
|
+
"format"
|
|
59
46
|
],
|
|
60
47
|
"license": "BSD-3-Clause",
|
|
61
|
-
"main": "./dist/index.js",
|
|
48
|
+
"main": "./dist/src/index.js",
|
|
62
49
|
"name": "slonik-interceptor-query-cache",
|
|
63
|
-
"nyc": {
|
|
64
|
-
"all": true,
|
|
65
|
-
"exclude": [
|
|
66
|
-
"src/bin",
|
|
67
|
-
"src/queries/*.js"
|
|
68
|
-
],
|
|
69
|
-
"include": [
|
|
70
|
-
"src/**/*.js"
|
|
71
|
-
],
|
|
72
|
-
"instrument": false,
|
|
73
|
-
"reporter": [
|
|
74
|
-
"html",
|
|
75
|
-
"text-summary"
|
|
76
|
-
],
|
|
77
|
-
"require": [
|
|
78
|
-
"@babel/register"
|
|
79
|
-
],
|
|
80
|
-
"silent": true,
|
|
81
|
-
"sourceMap": false
|
|
82
|
-
},
|
|
83
50
|
"repository": {
|
|
84
51
|
"type": "git",
|
|
85
52
|
"url": "https://github.com/gajus/slonik-interceptor-query-cache"
|
|
86
53
|
},
|
|
87
54
|
"scripts": {
|
|
88
|
-
"build": "
|
|
89
|
-
"lint": "eslint ./src ./test &&
|
|
55
|
+
"build": "del-cli ./dist && tsc",
|
|
56
|
+
"lint": "eslint ./src ./test && tsc --noEmit",
|
|
90
57
|
"test": "NODE_ENV=test nyc ava --verbose --serial"
|
|
91
58
|
},
|
|
92
|
-
"
|
|
59
|
+
"typings": "./dist/src/index.d.ts",
|
|
60
|
+
"version": "2.1.0",
|
|
61
|
+
"peerDependencies": {
|
|
62
|
+
"slonik": ">=27.0.0"
|
|
63
|
+
},
|
|
64
|
+
"dependencies": {
|
|
65
|
+
"roarr": "^7.14.0"
|
|
66
|
+
}
|
|
93
67
|
}
|
package/src/Logger.ts
ADDED
|
@@ -1,45 +1,51 @@
|
|
|
1
|
-
// @flow
|
|
2
|
-
|
|
3
1
|
import type {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
Interceptor,
|
|
3
|
+
Query,
|
|
4
|
+
QueryResultRow,
|
|
5
|
+
QueryResult,
|
|
8
6
|
} from 'slonik';
|
|
7
|
+
import {
|
|
8
|
+
Logger,
|
|
9
|
+
} from '../Logger';
|
|
9
10
|
import {
|
|
10
11
|
extractCacheAttributes,
|
|
11
12
|
} from '../utilities';
|
|
12
|
-
import log from '../Logger';
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
const log = Logger.child({
|
|
15
|
+
namespace: 'createQueryCacheInterceptor',
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
type Sandbox = {
|
|
19
|
+
cache: {
|
|
20
|
+
cacheAttributes: CacheAttributes,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
17
23
|
|
|
18
|
-
type
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|};
|
|
24
|
+
type CacheAttributes = {
|
|
25
|
+
ttl: number,
|
|
26
|
+
};
|
|
22
27
|
|
|
23
|
-
type
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
type Storage = {
|
|
29
|
+
get: (query: Query, cacheAttributes: CacheAttributes) => Promise<QueryResult<QueryResultRow> | null>,
|
|
30
|
+
set: (query: Query, cacheAttributes: CacheAttributes, queryResult: QueryResult<QueryResultRow>) => Promise<void>,
|
|
31
|
+
};
|
|
26
32
|
|
|
27
|
-
type
|
|
28
|
-
|
|
29
|
-
|
|
33
|
+
type ConfigurationInput = {
|
|
34
|
+
storage: Storage,
|
|
35
|
+
};
|
|
30
36
|
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
type Configuration = {
|
|
38
|
+
storage: Storage,
|
|
39
|
+
};
|
|
33
40
|
|
|
34
|
-
export
|
|
35
|
-
const configuration:
|
|
36
|
-
...defaultConfiguration,
|
|
41
|
+
export const createQueryCacheInterceptor = (configurationInput: ConfigurationInput): Interceptor => {
|
|
42
|
+
const configuration: Configuration = {
|
|
37
43
|
...configurationInput,
|
|
38
44
|
};
|
|
39
45
|
|
|
40
46
|
return {
|
|
41
47
|
beforeQueryExecution: async (context, query) => {
|
|
42
|
-
const cacheAttributes = context.sandbox
|
|
48
|
+
const cacheAttributes = (context.sandbox as Sandbox).cache?.cacheAttributes;
|
|
43
49
|
|
|
44
50
|
if (!cacheAttributes) {
|
|
45
51
|
return null;
|
|
@@ -58,7 +64,7 @@ export default (configurationInput?: ConfigurationInputType): InterceptorType =>
|
|
|
58
64
|
return null;
|
|
59
65
|
},
|
|
60
66
|
beforeQueryResult: async (context, query, result) => {
|
|
61
|
-
const cacheAttributes = context.sandbox
|
|
67
|
+
const cacheAttributes = (context.sandbox as Sandbox).cache?.cacheAttributes;
|
|
62
68
|
|
|
63
69
|
if (cacheAttributes) {
|
|
64
70
|
await configuration.storage.set(query, cacheAttributes, result);
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"allowSyntheticDefaultImports": true,
|
|
4
|
+
"declaration": true,
|
|
5
|
+
"esModuleInterop": true,
|
|
6
|
+
"forceConsistentCasingInFileNames": true,
|
|
7
|
+
"module": "commonjs",
|
|
8
|
+
"moduleResolution": "node",
|
|
9
|
+
"noImplicitAny": false,
|
|
10
|
+
"noImplicitReturns": true,
|
|
11
|
+
"noUnusedLocals": true,
|
|
12
|
+
"noUnusedParameters": false,
|
|
13
|
+
"outDir": "dist",
|
|
14
|
+
"skipLibCheck": true,
|
|
15
|
+
"strict": true,
|
|
16
|
+
"target": "es2018"
|
|
17
|
+
},
|
|
18
|
+
"exclude": [
|
|
19
|
+
"dist",
|
|
20
|
+
"node_modules"
|
|
21
|
+
],
|
|
22
|
+
"include": [
|
|
23
|
+
"src",
|
|
24
|
+
"test"
|
|
25
|
+
]
|
|
26
|
+
}
|
package/.flowconfig
DELETED
package/dist/Logger.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = void 0;
|
|
7
|
-
|
|
8
|
-
var _roarr = _interopRequireDefault(require("roarr"));
|
|
9
|
-
|
|
10
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
-
|
|
12
|
-
var _default = _roarr.default.child({
|
|
13
|
-
package: 'slonik-interceptor-query-cache'
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
exports.default = _default;
|
|
17
|
-
//# sourceMappingURL=Logger.js.map
|
package/dist/Logger.js.flow
DELETED
package/dist/Logger.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/Logger.js"],"names":["Logger","child","package"],"mappings":";;;;;;;AAEA;;;;eAEeA,eAAOC,KAAP,CAAa;AAC1BC,EAAAA,OAAO,EAAE;AADiB,CAAb,C","sourcesContent":["// @flow\n\nimport Logger from 'roarr';\n\nexport default Logger.child({\n package: 'slonik-interceptor-query-cache',\n});\n"],"file":"Logger.js"}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = void 0;
|
|
7
|
-
|
|
8
|
-
var _utilities = require("../utilities");
|
|
9
|
-
|
|
10
|
-
var _Logger = _interopRequireDefault(require("../Logger"));
|
|
11
|
-
|
|
12
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
-
|
|
14
|
-
// eslint-disable-next-line flowtype/no-weak-types
|
|
15
|
-
const defaultConfiguration = {};
|
|
16
|
-
|
|
17
|
-
const createQueryCacheInterceptor = configurationInput => {
|
|
18
|
-
const configuration = { ...defaultConfiguration,
|
|
19
|
-
...configurationInput
|
|
20
|
-
};
|
|
21
|
-
return {
|
|
22
|
-
beforeQueryExecution: async (context, query) => {
|
|
23
|
-
const cacheAttributes = context.sandbox.cache && context.sandbox.cache.cacheAttributes;
|
|
24
|
-
|
|
25
|
-
if (!cacheAttributes) {
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const maybeResult = await configuration.storage.get(query, cacheAttributes);
|
|
30
|
-
|
|
31
|
-
if (maybeResult) {
|
|
32
|
-
_Logger.default.info({
|
|
33
|
-
queryId: context.queryId
|
|
34
|
-
}, 'query is served from cache');
|
|
35
|
-
|
|
36
|
-
return maybeResult;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return null;
|
|
40
|
-
},
|
|
41
|
-
beforeQueryResult: async (context, query, result) => {
|
|
42
|
-
const cacheAttributes = context.sandbox.cache && context.sandbox.cache.cacheAttributes;
|
|
43
|
-
|
|
44
|
-
if (cacheAttributes) {
|
|
45
|
-
await configuration.storage.set(query, cacheAttributes, result);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return null;
|
|
49
|
-
},
|
|
50
|
-
beforeTransformQuery: async (context, query) => {
|
|
51
|
-
const cacheAttributes = (0, _utilities.extractCacheAttributes)(query.sql);
|
|
52
|
-
|
|
53
|
-
if (!cacheAttributes) {
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
context.sandbox.cache = {
|
|
58
|
-
cacheAttributes
|
|
59
|
-
};
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
var _default = createQueryCacheInterceptor;
|
|
66
|
-
exports.default = _default;
|
|
67
|
-
//# sourceMappingURL=createQueryCacheInterceptor.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/factories/createQueryCacheInterceptor.js"],"names":["defaultConfiguration","configurationInput","configuration","beforeQueryExecution","context","query","cacheAttributes","sandbox","cache","maybeResult","storage","get","log","info","queryId","beforeQueryResult","result","set","beforeTransformQuery","sql"],"mappings":";;;;;;;AAQA;;AAGA;;;;AAmBA;AACA,MAAMA,oBAA4B,GAAG,EAArC;;oCAEgBC,kB,IAAiE;AAC/E,QAAMC,aAAgC,GAAG,EACvC,GAAGF,oBADoC;AAEvC,OAAGC;AAFoC,GAAzC;AAKA,SAAO;AACLE,IAAAA,oBAAoB,EAAE,OAAOC,OAAP,EAAgBC,KAAhB,KAA0B;AAC9C,YAAMC,eAAe,GAAGF,OAAO,CAACG,OAAR,CAAgBC,KAAhB,IAAyBJ,OAAO,CAACG,OAAR,CAAgBC,KAAhB,CAAsBF,eAAvE;;AAEA,UAAI,CAACA,eAAL,EAAsB;AACpB,eAAO,IAAP;AACD;;AAED,YAAMG,WAAW,GAAG,MAAMP,aAAa,CAACQ,OAAd,CAAsBC,GAAtB,CAA0BN,KAA1B,EAAiCC,eAAjC,CAA1B;;AAEA,UAAIG,WAAJ,EAAiB;AACfG,wBAAIC,IAAJ,CAAS;AACPC,UAAAA,OAAO,EAAEV,OAAO,CAACU;AADV,SAAT,EAEG,4BAFH;;AAIA,eAAOL,WAAP;AACD;;AAED,aAAO,IAAP;AACD,KAnBI;AAoBLM,IAAAA,iBAAiB,EAAE,OAAOX,OAAP,EAAgBC,KAAhB,EAAuBW,MAAvB,KAAkC;AACnD,YAAMV,eAAe,GAAGF,OAAO,CAACG,OAAR,CAAgBC,KAAhB,IAAyBJ,OAAO,CAACG,OAAR,CAAgBC,KAAhB,CAAsBF,eAAvE;;AAEA,UAAIA,eAAJ,EAAqB;AACnB,cAAMJ,aAAa,CAACQ,OAAd,CAAsBO,GAAtB,CAA0BZ,KAA1B,EAAiCC,eAAjC,EAAkDU,MAAlD,CAAN;AACD;;AAED,aAAO,IAAP;AACD,KA5BI;AA6BLE,IAAAA,oBAAoB,EAAE,OAAOd,OAAP,EAAgBC,KAAhB,KAA0B;AAC9C,YAAMC,eAAe,GAAG,uCAAuBD,KAAK,CAACc,GAA7B,CAAxB;;AAEA,UAAI,CAACb,eAAL,EAAsB;AACpB,eAAO,IAAP;AACD;;AAEDF,MAAAA,OAAO,CAACG,OAAR,CAAgBC,KAAhB,GAAwB;AACtBF,QAAAA;AADsB,OAAxB;AAIA,aAAO,IAAP;AACD;AAzCI,GAAP;AA2CD,C","sourcesContent":["// @flow\n\nimport type {\n InterceptorType,\n QueryType,\n QueryResultRowType,\n QueryResultType,\n} from 'slonik';\nimport {\n extractCacheAttributes,\n} from '../utilities';\nimport log from '../Logger';\n\ntype CacheAttributesType = {|\n +ttl: number,\n|};\n\ntype StorageType = {|\n +get: (query: QueryType, cacheAttributes: CacheAttributesType) => Promise<QueryResultType<QueryResultRowType> | null>,\n +set: (query: QueryType, cacheAttributes: CacheAttributesType, queryResult: QueryResultType<QueryResultRowType>) => Promise<void>,\n|};\n\ntype ConfigurationInputType = {|\n +storage: StorageType,\n|};\n\ntype ConfigurationType = {|\n +storage: StorageType,\n|};\n\n// eslint-disable-next-line flowtype/no-weak-types\nconst defaultConfiguration: Object = {};\n\nexport default (configurationInput?: ConfigurationInputType): InterceptorType => {\n const configuration: ConfigurationType = {\n ...defaultConfiguration,\n ...configurationInput,\n };\n\n return {\n beforeQueryExecution: async (context, query) => {\n const cacheAttributes = context.sandbox.cache && context.sandbox.cache.cacheAttributes;\n\n if (!cacheAttributes) {\n return null;\n }\n\n const maybeResult = await configuration.storage.get(query, cacheAttributes);\n\n if (maybeResult) {\n log.info({\n queryId: context.queryId,\n }, 'query is served from cache');\n\n return maybeResult;\n }\n\n return null;\n },\n beforeQueryResult: async (context, query, result) => {\n const cacheAttributes = context.sandbox.cache && context.sandbox.cache.cacheAttributes;\n\n if (cacheAttributes) {\n await configuration.storage.set(query, cacheAttributes, result);\n }\n\n return null;\n },\n beforeTransformQuery: async (context, query) => {\n const cacheAttributes = extractCacheAttributes(query.sql);\n\n if (!cacheAttributes) {\n return null;\n }\n\n context.sandbox.cache = {\n cacheAttributes,\n };\n\n return null;\n },\n };\n};\n"],"file":"createQueryCacheInterceptor.js"}
|
package/dist/factories/index.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
Object.defineProperty(exports, "createQueryCacheInterceptor", {
|
|
7
|
-
enumerable: true,
|
|
8
|
-
get: function () {
|
|
9
|
-
return _createQueryCacheInterceptor.default;
|
|
10
|
-
}
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
var _createQueryCacheInterceptor = _interopRequireDefault(require("./createQueryCacheInterceptor"));
|
|
14
|
-
|
|
15
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
16
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/factories/index.js"],"names":[],"mappings":";;;;;;;;;;;;AAEA","sourcesContent":["// @flow\n\nexport {default as createQueryCacheInterceptor} from './createQueryCacheInterceptor';\n"],"file":"index.js"}
|
package/dist/index.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
Object.defineProperty(exports, "createQueryCacheInterceptor", {
|
|
7
|
-
enumerable: true,
|
|
8
|
-
get: function () {
|
|
9
|
-
return _factories.createQueryCacheInterceptor;
|
|
10
|
-
}
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
var _factories = require("./factories");
|
|
14
|
-
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.js"],"names":[],"mappings":";;;;;;;;;;;;AAEA","sourcesContent":["// @flow\n\nexport {\n createQueryCacheInterceptor,\n} from './factories';\n"],"file":"index.js"}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = void 0;
|
|
7
|
-
|
|
8
|
-
const extractCacheAttributes = subject => {
|
|
9
|
-
const matches = subject.match(/@cache-ttl (\d+)/);
|
|
10
|
-
|
|
11
|
-
if (matches) {
|
|
12
|
-
return {
|
|
13
|
-
ttl: Number(matches[1])
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
return null;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
var _default = extractCacheAttributes;
|
|
21
|
-
exports.default = _default;
|
|
22
|
-
//# sourceMappingURL=extractCacheAttributes.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/extractCacheAttributes.js"],"names":["subject","matches","match","ttl","Number"],"mappings":";;;;;;;+BAEgBA,O,IAAoB;AAClC,QAAMC,OAAO,GAAGD,OAAO,CAACE,KAAR,CAAc,kBAAd,CAAhB;;AAEA,MAAID,OAAJ,EAAa;AACX,WAAO;AACLE,MAAAA,GAAG,EAAEC,MAAM,CAACH,OAAO,CAAC,CAAD,CAAR;AADN,KAAP;AAGD;;AAED,SAAO,IAAP;AACD,C","sourcesContent":["// @flow\n\nexport default (subject: string) => {\n const matches = subject.match(/@cache-ttl (\\d+)/);\n\n if (matches) {\n return {\n ttl: Number(matches[1]),\n };\n }\n\n return null;\n};\n"],"file":"extractCacheAttributes.js"}
|
package/dist/utilities/index.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
Object.defineProperty(exports, "extractCacheAttributes", {
|
|
7
|
-
enumerable: true,
|
|
8
|
-
get: function () {
|
|
9
|
-
return _extractCacheAttributes.default;
|
|
10
|
-
}
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
var _extractCacheAttributes = _interopRequireDefault(require("./extractCacheAttributes"));
|
|
14
|
-
|
|
15
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
16
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/index.js"],"names":[],"mappings":";;;;;;;;;;;;AAEA","sourcesContent":["// @flow\n\nexport {default as extractCacheAttributes} from './extractCacheAttributes';\n"],"file":"index.js"}
|
package/src/Logger.js
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
// @flow
|
|
2
|
-
|
|
3
|
-
import type {
|
|
4
|
-
InterceptorType,
|
|
5
|
-
QueryType,
|
|
6
|
-
QueryResultRowType,
|
|
7
|
-
QueryResultType,
|
|
8
|
-
} from 'slonik';
|
|
9
|
-
import {
|
|
10
|
-
extractCacheAttributes,
|
|
11
|
-
} from '../utilities';
|
|
12
|
-
import log from '../Logger';
|
|
13
|
-
|
|
14
|
-
type CacheAttributesType = {|
|
|
15
|
-
+ttl: number,
|
|
16
|
-
|};
|
|
17
|
-
|
|
18
|
-
type StorageType = {|
|
|
19
|
-
+get: (query: QueryType, cacheAttributes: CacheAttributesType) => Promise<QueryResultType<QueryResultRowType> | null>,
|
|
20
|
-
+set: (query: QueryType, cacheAttributes: CacheAttributesType, queryResult: QueryResultType<QueryResultRowType>) => Promise<void>,
|
|
21
|
-
|};
|
|
22
|
-
|
|
23
|
-
type ConfigurationInputType = {|
|
|
24
|
-
+storage: StorageType,
|
|
25
|
-
|};
|
|
26
|
-
|
|
27
|
-
type ConfigurationType = {|
|
|
28
|
-
+storage: StorageType,
|
|
29
|
-
|};
|
|
30
|
-
|
|
31
|
-
// eslint-disable-next-line flowtype/no-weak-types
|
|
32
|
-
const defaultConfiguration: Object = {};
|
|
33
|
-
|
|
34
|
-
export default (configurationInput?: ConfigurationInputType): InterceptorType => {
|
|
35
|
-
const configuration: ConfigurationType = {
|
|
36
|
-
...defaultConfiguration,
|
|
37
|
-
...configurationInput,
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
return {
|
|
41
|
-
beforeQueryExecution: async (context, query) => {
|
|
42
|
-
const cacheAttributes = context.sandbox.cache && context.sandbox.cache.cacheAttributes;
|
|
43
|
-
|
|
44
|
-
if (!cacheAttributes) {
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const maybeResult = await configuration.storage.get(query, cacheAttributes);
|
|
49
|
-
|
|
50
|
-
if (maybeResult) {
|
|
51
|
-
log.info({
|
|
52
|
-
queryId: context.queryId,
|
|
53
|
-
}, 'query is served from cache');
|
|
54
|
-
|
|
55
|
-
return maybeResult;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return null;
|
|
59
|
-
},
|
|
60
|
-
beforeQueryResult: async (context, query, result) => {
|
|
61
|
-
const cacheAttributes = context.sandbox.cache && context.sandbox.cache.cacheAttributes;
|
|
62
|
-
|
|
63
|
-
if (cacheAttributes) {
|
|
64
|
-
await configuration.storage.set(query, cacheAttributes, result);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return null;
|
|
68
|
-
},
|
|
69
|
-
beforeTransformQuery: async (context, query) => {
|
|
70
|
-
const cacheAttributes = extractCacheAttributes(query.sql);
|
|
71
|
-
|
|
72
|
-
if (!cacheAttributes) {
|
|
73
|
-
return null;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
context.sandbox.cache = {
|
|
77
|
-
cacheAttributes,
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
return null;
|
|
81
|
-
},
|
|
82
|
-
};
|
|
83
|
-
};
|
package/src/factories/index.js
DELETED
package/src/utilities/index.js
DELETED