@autofleet/matmon 2.0.1 → 2.0.3
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/lib/index.d.ts +2 -2
- package/lib/index.js +2 -1
- package/lib/orm-cache/adapter.d.ts +2 -2
- package/lib/orm-cache/index.d.ts +1 -2
- package/lib/orm-cache/index.js +3 -4
- package/lib/orm-cache/sequelize-adapter.d.ts +2 -1
- package/lib/orm-cache/sequelize-adapter.js +52 -19
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { getNewLRU, getWithCacheSupport } from './cache';
|
|
2
2
|
import RedisCache from './redis';
|
|
3
|
-
import { ORMCache } from './orm-cache';
|
|
4
|
-
export { getNewLRU, getWithCacheSupport, RedisCache, ORMCache, };
|
|
3
|
+
import { ORMCache, ORMTypes } from './orm-cache';
|
|
4
|
+
export { getNewLRU, getWithCacheSupport, RedisCache, ORMCache, ORMTypes };
|
package/lib/index.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.ORMCache = exports.RedisCache = exports.getWithCacheSupport = exports.getNewLRU = void 0;
|
|
6
|
+
exports.ORMTypes = exports.ORMCache = exports.RedisCache = exports.getWithCacheSupport = exports.getNewLRU = void 0;
|
|
7
7
|
const cache_1 = require("./cache");
|
|
8
8
|
Object.defineProperty(exports, "getNewLRU", { enumerable: true, get: function () { return cache_1.getNewLRU; } });
|
|
9
9
|
Object.defineProperty(exports, "getWithCacheSupport", { enumerable: true, get: function () { return cache_1.getWithCacheSupport; } });
|
|
@@ -11,3 +11,4 @@ const redis_1 = __importDefault(require("./redis"));
|
|
|
11
11
|
exports.RedisCache = redis_1.default;
|
|
12
12
|
const orm_cache_1 = require("./orm-cache");
|
|
13
13
|
Object.defineProperty(exports, "ORMCache", { enumerable: true, get: function () { return orm_cache_1.ORMCache; } });
|
|
14
|
+
Object.defineProperty(exports, "ORMTypes", { enumerable: true, get: function () { return orm_cache_1.ORMTypes; } });
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import RedisCache from '../redis';
|
|
2
2
|
export interface ModelOptions {
|
|
3
3
|
name: string;
|
|
4
|
-
associations
|
|
4
|
+
associations?: AssociationOptions[];
|
|
5
5
|
}
|
|
6
6
|
export interface AssociationOptions {
|
|
7
7
|
name: string;
|
|
8
8
|
alias: string;
|
|
9
9
|
accessKey?: string;
|
|
10
|
-
|
|
10
|
+
innerAssociation?: AssociationOptions;
|
|
11
11
|
}
|
|
12
12
|
export interface Adapter {
|
|
13
13
|
ormInstance: any;
|
package/lib/orm-cache/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ModelOptions } from './adapter';
|
|
2
|
-
declare enum ORMTypes {
|
|
2
|
+
export declare enum ORMTypes {
|
|
3
3
|
SEQUELIZE = "sequelize"
|
|
4
4
|
}
|
|
5
5
|
interface ORMCacheOptions {
|
|
@@ -7,7 +7,6 @@ interface ORMCacheOptions {
|
|
|
7
7
|
models: ModelOptions[];
|
|
8
8
|
ormInstance: any;
|
|
9
9
|
debug: boolean;
|
|
10
|
-
ttl: number;
|
|
11
10
|
}
|
|
12
11
|
export declare const ORMCache: (options: ORMCacheOptions) => void;
|
|
13
12
|
export {};
|
package/lib/orm-cache/index.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.ORMCache = void 0;
|
|
6
|
+
exports.ORMCache = exports.ORMTypes = void 0;
|
|
7
7
|
const sequelize_adapter_1 = __importDefault(require("./sequelize-adapter"));
|
|
8
8
|
const errors_1 = require("./errors");
|
|
9
9
|
const redis_1 = __importDefault(require("../redis"));
|
|
@@ -11,7 +11,7 @@ const logger_1 = __importDefault(require("../logger"));
|
|
|
11
11
|
var ORMTypes;
|
|
12
12
|
(function (ORMTypes) {
|
|
13
13
|
ORMTypes["SEQUELIZE"] = "sequelize";
|
|
14
|
-
})(ORMTypes || (ORMTypes = {}));
|
|
14
|
+
})(ORMTypes = exports.ORMTypes || (exports.ORMTypes = {}));
|
|
15
15
|
const ORMInstanceFactory = (options) => {
|
|
16
16
|
switch (options.type) {
|
|
17
17
|
case ORMTypes.SEQUELIZE: {
|
|
@@ -23,13 +23,12 @@ const ORMInstanceFactory = (options) => {
|
|
|
23
23
|
}
|
|
24
24
|
};
|
|
25
25
|
exports.ORMCache = (options) => {
|
|
26
|
-
const {
|
|
26
|
+
const { models } = options;
|
|
27
27
|
logger_1.default.info('Starting ORM Cache', { options });
|
|
28
28
|
const adapter = ORMInstanceFactory(options);
|
|
29
29
|
const cache = new redis_1.default({
|
|
30
30
|
host: process.env.REDIS_HOST,
|
|
31
31
|
port: process.env.REDIS_PORT,
|
|
32
|
-
ttl: options.ttl || 90,
|
|
33
32
|
});
|
|
34
33
|
// eslint-disable-next-line array-callback-return
|
|
35
34
|
models.map((modelOptions) => {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Sequelize } from 'sequelize';
|
|
2
|
-
import { Adapter, ModelOptions } from './adapter';
|
|
2
|
+
import { Adapter, AssociationOptions, ModelOptions } from './adapter';
|
|
3
3
|
import RedisCache from '../redis';
|
|
4
4
|
export default class SequelizeAdapter implements Adapter {
|
|
5
5
|
ormInstance: Sequelize;
|
|
6
6
|
debugMode: boolean;
|
|
7
7
|
constructor(sequelize: Sequelize, debug: any);
|
|
8
8
|
getModel(modelName: string): any;
|
|
9
|
+
getModelDependencies(modelName: string): AssociationOptions[];
|
|
9
10
|
debug(message: any, payload: any): void;
|
|
10
11
|
injectGetWithCacheFunction(cache: RedisCache, modelOptions: ModelOptions): void;
|
|
11
12
|
addInvalidationHooks(cache: RedisCache, modelOptions: ModelOptions): void;
|
|
@@ -15,27 +15,30 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
const logger_1 = __importDefault(require("../logger"));
|
|
16
16
|
const util_1 = require("util");
|
|
17
17
|
const { AF_SERVICE_NAME } = process.env;
|
|
18
|
+
const ORM_CACHE_PREFIX = 'ormCache';
|
|
18
19
|
const INVALIDATION_HOOKS = ['afterSave', 'afterUpdate', 'afterDestroy'];
|
|
19
20
|
const BULK_HOOKS = ['beforeBulkUpdate', 'beforeBulkDestroy'];
|
|
20
|
-
const generateInstanceKey = (
|
|
21
|
-
const generateDependencyKey = (modelName, associationName, associationId) => `${AF_SERVICE_NAME}:${modelName}_${associationName}_${associationId}_DEPENDENCIES`;
|
|
22
|
-
const getAssociation = (instance, associationOptions, associationId) => {
|
|
23
|
-
const accessKey = associationOptions.accessKey || 'id';
|
|
24
|
-
if (Array.isArray(instance[associationOptions.alias])) {
|
|
25
|
-
return instance[associationOptions.alias].find(association => association[accessKey] === associationId);
|
|
26
|
-
}
|
|
27
|
-
return instance[associationOptions.alias];
|
|
28
|
-
};
|
|
21
|
+
const generateInstanceKey = (name, id) => `${AF_SERVICE_NAME}:${ORM_CACHE_PREFIX}:${name}_${id}`;
|
|
22
|
+
const generateDependencyKey = (modelName, associationName, associationId) => `${AF_SERVICE_NAME}:${ORM_CACHE_PREFIX}:${modelName}_${associationName}_${associationId}_DEPENDENCIES`;
|
|
29
23
|
const getInstanceDependencyKeys = (modelOptions, instance) => {
|
|
30
24
|
const keys = modelOptions.associations
|
|
31
|
-
.filter((
|
|
25
|
+
.filter((associationOptions) => instance[associationOptions.alias])
|
|
32
26
|
.map((associationOptions) => {
|
|
33
|
-
const accessKey = associationOptions.accessKey
|
|
27
|
+
const accessKey = associationOptions.accessKey;
|
|
28
|
+
const depKeys = [];
|
|
34
29
|
if (Array.isArray(instance[associationOptions.alias])) {
|
|
35
|
-
|
|
36
|
-
.
|
|
30
|
+
instance[associationOptions.alias].map(associationInstance => {
|
|
31
|
+
depKeys.push(generateDependencyKey(modelOptions.name, associationOptions.name, associationInstance[accessKey]));
|
|
32
|
+
if (associationOptions.innerAssociation &&
|
|
33
|
+
associationInstance[associationOptions.innerAssociation.alias]) {
|
|
34
|
+
depKeys.push(generateDependencyKey(modelOptions.name, associationOptions.innerAssociation.name, associationInstance[associationOptions.innerAssociation.alias][associationOptions.innerAssociation.accessKey]));
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
return depKeys;
|
|
37
38
|
}
|
|
38
|
-
return [
|
|
39
|
+
return [
|
|
40
|
+
generateDependencyKey(modelOptions.name, associationOptions.name, instance[associationOptions.alias][accessKey]),
|
|
41
|
+
];
|
|
39
42
|
});
|
|
40
43
|
return keys.reduce((flattenArray, array) => flattenArray.concat(array), []);
|
|
41
44
|
};
|
|
@@ -56,6 +59,28 @@ class SequelizeAdapter {
|
|
|
56
59
|
getModel(modelName) {
|
|
57
60
|
return this.ormInstance.models[modelName];
|
|
58
61
|
}
|
|
62
|
+
getModelDependencies(modelName) {
|
|
63
|
+
const { associations } = this.ormInstance.models[modelName];
|
|
64
|
+
return [
|
|
65
|
+
...Object.keys(associations).map(association => {
|
|
66
|
+
const sequelizeAssociation = associations[association];
|
|
67
|
+
const associationOptions = {
|
|
68
|
+
alias: sequelizeAssociation.as,
|
|
69
|
+
name: sequelizeAssociation.target.name,
|
|
70
|
+
accessKey: sequelizeAssociation.target.primaryKeyAttribute,
|
|
71
|
+
};
|
|
72
|
+
if (sequelizeAssociation.through) {
|
|
73
|
+
const relationModel = sequelizeAssociation.through.model;
|
|
74
|
+
associationOptions.innerAssociation = {
|
|
75
|
+
alias: relationModel.name,
|
|
76
|
+
name: relationModel.name,
|
|
77
|
+
accessKey: relationModel.primaryKeyAttribute,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
return associationOptions;
|
|
81
|
+
}),
|
|
82
|
+
];
|
|
83
|
+
}
|
|
59
84
|
debug(message, payload) {
|
|
60
85
|
if (this.debugMode) {
|
|
61
86
|
logger_1.default.info(`[ORM_CACHE Debug] ${message}`, payload);
|
|
@@ -64,7 +89,7 @@ class SequelizeAdapter {
|
|
|
64
89
|
injectGetWithCacheFunction(cache, modelOptions) {
|
|
65
90
|
const addDependencies = (instance) => __awaiter(this, void 0, void 0, function* () {
|
|
66
91
|
const dependencyKeys = getInstanceDependencyKeys(modelOptions, instance);
|
|
67
|
-
const instanceKey = generateInstanceKey(modelOptions, instance.id);
|
|
92
|
+
const instanceKey = generateInstanceKey(modelOptions.name, instance.id);
|
|
68
93
|
this.debug('Adding dependencies', { instanceKey, dependencyKeys });
|
|
69
94
|
const addDependenciesMulti = cache.getClient().multi();
|
|
70
95
|
const addDependenciesMultiAsync = util_1.promisify(addDependenciesMulti.exec).bind(addDependenciesMulti);
|
|
@@ -73,18 +98,19 @@ class SequelizeAdapter {
|
|
|
73
98
|
});
|
|
74
99
|
const model = this.getModel(modelOptions.name);
|
|
75
100
|
model.findByPkCached = (id, scopes, options) => __awaiter(this, void 0, void 0, function* () {
|
|
76
|
-
const cacheKey = generateInstanceKey(modelOptions, id);
|
|
101
|
+
const cacheKey = generateInstanceKey(modelOptions.name, id);
|
|
77
102
|
let value = JSON.parse(yield cache.getClient().getAsync(cacheKey));
|
|
78
103
|
if (!value) {
|
|
79
104
|
this.debug('Value not found in cache, looking in db', { id, cacheKey });
|
|
80
105
|
value = yield model.scope(scopes).findByPk(id, options);
|
|
81
106
|
this.debug('Value from DB', { value: value || 'not found', cacheKey });
|
|
82
|
-
|
|
107
|
+
yield Promise.all([
|
|
83
108
|
cache.getClient().setAsync(cacheKey, JSON.stringify(value)),
|
|
84
109
|
value && addDependencies(value),
|
|
85
110
|
]);
|
|
86
111
|
}
|
|
87
112
|
else {
|
|
113
|
+
value = this.getModel(modelOptions.name).build(value, { isNewRecord: false, include: options.include });
|
|
88
114
|
this.debug('Found cached value', { value, id, cacheKey });
|
|
89
115
|
}
|
|
90
116
|
return value;
|
|
@@ -93,7 +119,7 @@ class SequelizeAdapter {
|
|
|
93
119
|
addInvalidationHooks(cache, modelOptions) {
|
|
94
120
|
const invalidateModelInstance = (instance) => __awaiter(this, void 0, void 0, function* () {
|
|
95
121
|
const dependencyKeys = getInstanceDependencyKeys(modelOptions, instance);
|
|
96
|
-
const instanceKey = generateInstanceKey(modelOptions, instance.id);
|
|
122
|
+
const instanceKey = generateInstanceKey(modelOptions.name, instance.id);
|
|
97
123
|
this.debug('Removing dependencies', { instance, instanceKey, dependencyKeys });
|
|
98
124
|
const removeMulti = cache.getClient().multi();
|
|
99
125
|
const removeMultiAsync = util_1.promisify(removeMulti.exec).bind(removeMulti);
|
|
@@ -122,10 +148,17 @@ class SequelizeAdapter {
|
|
|
122
148
|
const model = this.getModel(modelOptions.name);
|
|
123
149
|
INVALIDATION_HOOKS.map(hook => model.addHook(hook, (instance, options) => handleTransactionHook(instance, options, instance => invalidateModelInstance(instance))));
|
|
124
150
|
BULK_HOOKS.map(hook => model.addHook(hook, options => options.individualHook = true));
|
|
151
|
+
modelOptions.associations = this.getModelDependencies(modelOptions.name);
|
|
152
|
+
this.debug(`Adding Invalidations Hooks to ${modelOptions.name}'s associations`, { associations: modelOptions.associations });
|
|
125
153
|
modelOptions.associations.map((associationOptions) => {
|
|
126
154
|
const associationModel = this.getModel(associationOptions.name);
|
|
127
|
-
INVALIDATION_HOOKS.map(hook => associationModel.addHook(hook, (instance, options) => handleTransactionHook(instance, options, associationInstance => invalidateModelInstanceByAssociation(associationOptions.name, associationInstance[associationOptions.accessKey
|
|
155
|
+
INVALIDATION_HOOKS.map(hook => associationModel.addHook(hook, (instance, options) => handleTransactionHook(instance, options, associationInstance => invalidateModelInstanceByAssociation(associationOptions.name, associationInstance[associationOptions.accessKey]))));
|
|
128
156
|
BULK_HOOKS.map(hook => associationModel.addHook(hook, options => options.individualHook = true));
|
|
157
|
+
if (associationOptions.innerAssociation) {
|
|
158
|
+
const innerAssociationModel = this.getModel(associationOptions.innerAssociation.name);
|
|
159
|
+
INVALIDATION_HOOKS.map(hook => innerAssociationModel.addHook(hook, (instance, options) => handleTransactionHook(instance, options, innerAssociationInstance => invalidateModelInstanceByAssociation(associationOptions.innerAssociation.name, innerAssociationInstance[associationOptions.innerAssociation.accessKey]))));
|
|
160
|
+
BULK_HOOKS.map(hook => innerAssociationModel.addHook(hook, options => options.individualHook = true));
|
|
161
|
+
}
|
|
129
162
|
});
|
|
130
163
|
}
|
|
131
164
|
}
|