@kapeta/local-cluster-service 0.16.0 → 0.16.2
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/CHANGELOG.md +14 -0
- package/dist/cjs/src/RepositoryWatcher.d.ts +4 -3
- package/dist/cjs/src/RepositoryWatcher.js +29 -23
- package/dist/cjs/src/assetManager.d.ts +4 -6
- package/dist/cjs/src/assetManager.js +49 -54
- package/dist/cjs/src/assets/routes.js +2 -2
- package/dist/cjs/src/cacheManager.d.ts +16 -0
- package/dist/cjs/src/cacheManager.js +47 -0
- package/dist/cjs/src/definitionsManager.d.ts +3 -4
- package/dist/cjs/src/definitionsManager.js +10 -21
- package/dist/cjs/src/repositoryManager.d.ts +7 -2
- package/dist/cjs/src/repositoryManager.js +10 -10
- package/dist/cjs/src/types.d.ts +2 -0
- package/dist/cjs/src/utils/utils.js +1 -1
- package/dist/esm/src/RepositoryWatcher.d.ts +4 -3
- package/dist/esm/src/RepositoryWatcher.js +29 -23
- package/dist/esm/src/assetManager.d.ts +4 -6
- package/dist/esm/src/assetManager.js +49 -54
- package/dist/esm/src/assets/routes.js +2 -2
- package/dist/esm/src/cacheManager.d.ts +16 -0
- package/dist/esm/src/cacheManager.js +39 -0
- package/dist/esm/src/definitionsManager.d.ts +3 -4
- package/dist/esm/src/definitionsManager.js +10 -21
- package/dist/esm/src/repositoryManager.d.ts +7 -2
- package/dist/esm/src/repositoryManager.js +10 -10
- package/dist/esm/src/types.d.ts +2 -0
- package/dist/esm/src/utils/utils.js +1 -1
- package/package.json +1 -1
- package/src/RepositoryWatcher.ts +30 -26
- package/src/assetManager.ts +63 -60
- package/src/assets/routes.ts +2 -2
- package/src/cacheManager.ts +54 -0
- package/src/definitionsManager.ts +13 -33
- package/src/repositoryManager.ts +11 -12
- package/src/types.ts +2 -2
- package/src/utils/utils.ts +1 -1
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
## [0.16.2](https://github.com/kapetacom/local-cluster-service/compare/v0.16.1...v0.16.2) (2023-08-12)
|
2
|
+
|
3
|
+
|
4
|
+
### Bug Fixes
|
5
|
+
|
6
|
+
* Be smarter about caching ([086ffe4](https://github.com/kapetacom/local-cluster-service/commit/086ffe416a044a8d9dc5e33aa879960d3e3c2b1a))
|
7
|
+
|
8
|
+
## [0.16.1](https://github.com/kapetacom/local-cluster-service/compare/v0.16.0...v0.16.1) (2023-08-11)
|
9
|
+
|
10
|
+
|
11
|
+
### Bug Fixes
|
12
|
+
|
13
|
+
* Instead of ignoring we set source-of-change ([ecd23c4](https://github.com/kapetacom/local-cluster-service/commit/ecd23c4c3316a189038a1f2f2f2c8794f6153261))
|
14
|
+
|
1
15
|
# [0.16.0](https://github.com/kapetacom/local-cluster-service/compare/v0.15.3...v0.16.0) (2023-08-11)
|
2
16
|
|
3
17
|
|
@@ -1,15 +1,16 @@
|
|
1
|
+
import { SourceOfChange } from './types';
|
1
2
|
export declare class RepositoryWatcher {
|
2
3
|
private watcher?;
|
3
4
|
private disabled;
|
4
5
|
private readonly baseDir;
|
5
6
|
private allDefinitions;
|
6
7
|
private symbolicLinks;
|
7
|
-
private
|
8
|
+
private sourceOfChange;
|
8
9
|
constructor();
|
9
10
|
setDisabled(disabled: boolean): void;
|
10
11
|
watch(): void;
|
11
|
-
|
12
|
-
|
12
|
+
setSourceOfChangeFor(file: string, source: SourceOfChange): Promise<void>;
|
13
|
+
clearSourceOfChangeFor(file: string): Promise<void>;
|
13
14
|
unwatch(): Promise<void>;
|
14
15
|
private getAssetIdentity;
|
15
16
|
private handleFileChange;
|
@@ -12,12 +12,7 @@ const yaml_1 = __importDefault(require("yaml"));
|
|
12
12
|
const nodejs_utils_1 = require("@kapeta/nodejs-utils");
|
13
13
|
const lodash_1 = __importDefault(require("lodash"));
|
14
14
|
const socketManager_1 = require("./socketManager");
|
15
|
-
const
|
16
|
-
const assetManager_1 = require("./assetManager");
|
17
|
-
function clearAllCaches() {
|
18
|
-
definitionsManager_1.definitionsManager.clearCache();
|
19
|
-
assetManager_1.assetManager.clearCache();
|
20
|
-
}
|
15
|
+
const cacheManager_1 = require("./cacheManager");
|
21
16
|
const KAPETA_YML_RX = /^kapeta.ya?ml$/;
|
22
17
|
class RepositoryWatcher {
|
23
18
|
watcher;
|
@@ -25,7 +20,7 @@ class RepositoryWatcher {
|
|
25
20
|
baseDir;
|
26
21
|
allDefinitions = [];
|
27
22
|
symbolicLinks = {};
|
28
|
-
|
23
|
+
sourceOfChange = new Map();
|
29
24
|
constructor() {
|
30
25
|
this.baseDir = local_cluster_config_1.default.getRepositoryBasedir();
|
31
26
|
}
|
@@ -61,18 +56,28 @@ class RepositoryWatcher {
|
|
61
56
|
return;
|
62
57
|
}
|
63
58
|
}
|
64
|
-
async
|
65
|
-
this.
|
66
|
-
|
67
|
-
|
68
|
-
|
59
|
+
async setSourceOfChangeFor(file, source) {
|
60
|
+
this.sourceOfChange.set(file, source);
|
61
|
+
try {
|
62
|
+
const realPath = await fs_extra_1.default.realpath(file);
|
63
|
+
if (realPath !== file) {
|
64
|
+
this.sourceOfChange.set(realPath, source);
|
65
|
+
}
|
66
|
+
}
|
67
|
+
catch (e) {
|
68
|
+
// Ignore
|
69
69
|
}
|
70
70
|
}
|
71
|
-
async
|
72
|
-
this.
|
73
|
-
|
74
|
-
|
75
|
-
|
71
|
+
async clearSourceOfChangeFor(file) {
|
72
|
+
this.sourceOfChange.delete(file);
|
73
|
+
try {
|
74
|
+
const realPath = await fs_extra_1.default.realpath(file);
|
75
|
+
if (realPath !== file) {
|
76
|
+
this.sourceOfChange.delete(realPath);
|
77
|
+
}
|
78
|
+
}
|
79
|
+
catch (e) {
|
80
|
+
// Ignore
|
76
81
|
}
|
77
82
|
}
|
78
83
|
async unwatch() {
|
@@ -127,9 +132,6 @@ class RepositoryWatcher {
|
|
127
132
|
if (!path) {
|
128
133
|
return;
|
129
134
|
}
|
130
|
-
if (this.ignoredFiles.has(path)) {
|
131
|
-
return;
|
132
|
-
}
|
133
135
|
//console.log('File changed', eventName, path);
|
134
136
|
const assetIdentity = await this.getAssetIdentity(path);
|
135
137
|
if (!assetIdentity) {
|
@@ -153,9 +155,12 @@ class RepositoryWatcher {
|
|
153
155
|
await this.updateSymlinkTarget(path);
|
154
156
|
}
|
155
157
|
}
|
156
|
-
|
158
|
+
const sourceOfChange = this.sourceOfChange.get(path) ?? 'filesystem';
|
159
|
+
await this.checkForChange(assetIdentity, sourceOfChange);
|
160
|
+
// We consume the sourceOfChange when the file is changed
|
161
|
+
this.sourceOfChange.delete(path);
|
157
162
|
}
|
158
|
-
async checkForChange(assetIdentity) {
|
163
|
+
async checkForChange(assetIdentity, sourceOfChange) {
|
159
164
|
const ymlPath = node_path_1.default.join(this.baseDir, assetIdentity.handle, assetIdentity.name, assetIdentity.version, 'kapeta.yml');
|
160
165
|
const newDefinitions = local_cluster_config_1.default.getDefinitions();
|
161
166
|
const newDefinition = newDefinitions.find((d) => d.ymlPath === ymlPath);
|
@@ -194,11 +199,12 @@ class RepositoryWatcher {
|
|
194
199
|
type,
|
195
200
|
definition: newDefinition?.definition ?? currentDefinition?.definition,
|
196
201
|
asset: assetIdentity,
|
202
|
+
sourceOfChange,
|
197
203
|
};
|
198
204
|
this.allDefinitions = newDefinitions;
|
199
205
|
//console.log('Asset changed', payload);
|
200
206
|
socketManager_1.socketManager.emitGlobal('asset-change', payload);
|
201
|
-
|
207
|
+
cacheManager_1.cacheManager.flush();
|
202
208
|
}
|
203
209
|
async exists(path) {
|
204
210
|
try {
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import { Definition } from '@kapeta/local-cluster-config';
|
2
2
|
import { BlockDefinition } from '@kapeta/schemas';
|
3
|
+
import { SourceOfChange } from './types';
|
3
4
|
export interface EnrichedAsset {
|
4
5
|
ref: string;
|
5
6
|
editable: boolean;
|
@@ -11,9 +12,6 @@ export interface EnrichedAsset {
|
|
11
12
|
ymlPath: string;
|
12
13
|
}
|
13
14
|
declare class AssetManager {
|
14
|
-
private cache;
|
15
|
-
constructor();
|
16
|
-
clearCache(): void;
|
17
15
|
/**
|
18
16
|
*
|
19
17
|
* @param {string[]} [assetKinds]
|
@@ -23,12 +21,12 @@ declare class AssetManager {
|
|
23
21
|
getPlans(): EnrichedAsset[];
|
24
22
|
getPlan(ref: string, noCache?: boolean): Promise<Definition>;
|
25
23
|
getAsset(ref: string, noCache?: boolean, autoFetch?: boolean): Promise<EnrichedAsset | undefined>;
|
26
|
-
createAsset(path: string, yaml: BlockDefinition): Promise<EnrichedAsset[]>;
|
27
|
-
updateAsset(ref: string, yaml: BlockDefinition): Promise<void>;
|
28
|
-
private maybeGenerateCode;
|
24
|
+
createAsset(path: string, yaml: BlockDefinition, sourceOfChange?: SourceOfChange): Promise<EnrichedAsset[]>;
|
25
|
+
updateAsset(ref: string, yaml: BlockDefinition, sourceOfChange?: SourceOfChange): Promise<void>;
|
29
26
|
importFile(filePath: string): Promise<EnrichedAsset[]>;
|
30
27
|
unregisterAsset(ref: string): Promise<void>;
|
31
28
|
installAsset(ref: string): Promise<import("./taskManager").Task<void>[] | undefined>;
|
29
|
+
private maybeGenerateCode;
|
32
30
|
}
|
33
31
|
export declare const assetManager: AssetManager;
|
34
32
|
export {};
|
@@ -7,7 +7,6 @@ exports.assetManager = void 0;
|
|
7
7
|
const node_path_1 = __importDefault(require("node:path"));
|
8
8
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
9
9
|
const yaml_1 = __importDefault(require("yaml"));
|
10
|
-
const node_cache_1 = __importDefault(require("node-cache"));
|
11
10
|
const codeGeneratorManager_1 = require("./codeGeneratorManager");
|
12
11
|
const progressListener_1 = require("./progressListener");
|
13
12
|
const nodejs_utils_1 = require("@kapeta/nodejs-utils");
|
@@ -16,10 +15,9 @@ const nodejs_registry_utils_1 = require("@kapeta/nodejs-registry-utils");
|
|
16
15
|
const definitionsManager_1 = require("./definitionsManager");
|
17
16
|
const utils_1 = require("./utils/utils");
|
18
17
|
const taskManager_1 = require("./taskManager");
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
}
|
18
|
+
const cacheManager_1 = require("./cacheManager");
|
19
|
+
const CACHE_TTL = 60 * 60 * 1000; // 1 hour
|
20
|
+
const toKey = (ref) => `assetManager:asset:${ref}`;
|
23
21
|
function enrichAsset(asset) {
|
24
22
|
return {
|
25
23
|
ref: `kapeta://${asset.definition.metadata.name}:${asset.version}`,
|
@@ -45,15 +43,6 @@ function parseRef(ref) {
|
|
45
43
|
return [out[0].toLowerCase(), out[1].toLowerCase()];
|
46
44
|
}
|
47
45
|
class AssetManager {
|
48
|
-
cache;
|
49
|
-
constructor() {
|
50
|
-
this.cache = new node_cache_1.default({
|
51
|
-
stdTTL: 60 * 60, // 1 hour
|
52
|
-
});
|
53
|
-
}
|
54
|
-
clearCache() {
|
55
|
-
this.cache.flushAll();
|
56
|
-
}
|
57
46
|
/**
|
58
47
|
*
|
59
48
|
* @param {string[]} [assetKinds]
|
@@ -85,9 +74,9 @@ class AssetManager {
|
|
85
74
|
}
|
86
75
|
async getAsset(ref, noCache = false, autoFetch = true) {
|
87
76
|
ref = (0, utils_1.normalizeKapetaUri)(ref);
|
88
|
-
const cacheKey =
|
89
|
-
if (!noCache &&
|
90
|
-
return
|
77
|
+
const cacheKey = toKey(ref);
|
78
|
+
if (!noCache && cacheManager_1.cacheManager.has(cacheKey)) {
|
79
|
+
return cacheManager_1.cacheManager.get(cacheKey);
|
91
80
|
}
|
92
81
|
const uri = (0, nodejs_utils_1.parseKapetaUri)(ref);
|
93
82
|
if (autoFetch) {
|
@@ -101,11 +90,11 @@ class AssetManager {
|
|
101
90
|
throw new Error('Asset not found: ' + ref);
|
102
91
|
}
|
103
92
|
if (asset) {
|
104
|
-
|
93
|
+
cacheManager_1.cacheManager.set(cacheKey, asset, CACHE_TTL);
|
105
94
|
}
|
106
95
|
return asset;
|
107
96
|
}
|
108
|
-
async createAsset(path, yaml) {
|
97
|
+
async createAsset(path, yaml, sourceOfChange = 'filesystem') {
|
109
98
|
if (await fs_extra_1.default.pathExists(path)) {
|
110
99
|
throw new Error('File already exists: ' + path);
|
111
100
|
}
|
@@ -113,14 +102,22 @@ class AssetManager {
|
|
113
102
|
if (!(await fs_extra_1.default.pathExists(dirName))) {
|
114
103
|
await fs_extra_1.default.mkdirp(dirName);
|
115
104
|
}
|
105
|
+
await repositoryManager_1.repositoryManager.setSourceOfChangeFor(path, sourceOfChange);
|
116
106
|
await fs_extra_1.default.writeFile(path, yaml_1.default.stringify(yaml));
|
117
107
|
const asset = await this.importFile(path);
|
118
|
-
|
108
|
+
asset.forEach((a) => {
|
109
|
+
const ref = (0, utils_1.normalizeKapetaUri)(a.ref);
|
110
|
+
const key = toKey(ref);
|
111
|
+
cacheManager_1.cacheManager.set(key, a, CACHE_TTL);
|
112
|
+
});
|
113
|
+
definitionsManager_1.definitionsManager.clearCache();
|
114
|
+
console.log(`Created asset at: ${path}`);
|
119
115
|
const ref = `kapeta://${yaml.metadata.name}:local`;
|
120
116
|
this.maybeGenerateCode(ref, path, yaml);
|
121
117
|
return asset;
|
122
118
|
}
|
123
|
-
async updateAsset(ref, yaml) {
|
119
|
+
async updateAsset(ref, yaml, sourceOfChange = 'filesystem') {
|
120
|
+
ref = (0, utils_1.normalizeKapetaUri)(ref);
|
124
121
|
const asset = await this.getAsset(ref, true, false);
|
125
122
|
if (!asset) {
|
126
123
|
throw new Error('Attempted to update unknown asset: ' + ref);
|
@@ -131,36 +128,12 @@ class AssetManager {
|
|
131
128
|
if (!asset.ymlPath) {
|
132
129
|
throw new Error('Attempted to update corrupted asset: ' + ref);
|
133
130
|
}
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
this.maybeGenerateCode(asset.ref, asset.ymlPath, yaml);
|
141
|
-
}
|
142
|
-
finally {
|
143
|
-
//We need to wait a bit for the disk to settle before we can resume watching
|
144
|
-
setTimeout(async () => {
|
145
|
-
try {
|
146
|
-
await repositoryManager_1.repositoryManager.resumeChangedFor(path);
|
147
|
-
}
|
148
|
-
catch (e) { }
|
149
|
-
}, 500);
|
150
|
-
}
|
151
|
-
}
|
152
|
-
maybeGenerateCode(ref, ymlPath, block) {
|
153
|
-
ref = (0, utils_1.normalizeKapetaUri)(ref);
|
154
|
-
if (codeGeneratorManager_1.codeGeneratorManager.canGenerateCode(block)) {
|
155
|
-
const assetTitle = block.metadata.title ? block.metadata.title : (0, nodejs_utils_1.parseKapetaUri)(block.metadata.name).name;
|
156
|
-
taskManager_1.taskManager.add(`codegen:${ref}`, async () => {
|
157
|
-
await codeGeneratorManager_1.codeGeneratorManager.generate(ymlPath, block);
|
158
|
-
}, {
|
159
|
-
name: `Generating code for ${assetTitle}`,
|
160
|
-
});
|
161
|
-
return true;
|
162
|
-
}
|
163
|
-
return false;
|
131
|
+
await repositoryManager_1.repositoryManager.setSourceOfChangeFor(asset.ymlPath, sourceOfChange);
|
132
|
+
await fs_extra_1.default.writeFile(asset.ymlPath, yaml_1.default.stringify(yaml));
|
133
|
+
console.log(`Updated asset at: ${asset.ymlPath}`);
|
134
|
+
cacheManager_1.cacheManager.remove(toKey(ref));
|
135
|
+
definitionsManager_1.definitionsManager.clearCache();
|
136
|
+
this.maybeGenerateCode(asset.ref, asset.ymlPath, yaml);
|
164
137
|
}
|
165
138
|
async importFile(filePath) {
|
166
139
|
if (filePath.startsWith('file://')) {
|
@@ -173,8 +146,12 @@ class AssetManager {
|
|
173
146
|
const assetInfos = yaml_1.default.parseAllDocuments(content.toString()).map((doc) => doc.toJSON());
|
174
147
|
await nodejs_registry_utils_1.Actions.link(new progressListener_1.ProgressListener(), node_path_1.default.dirname(filePath));
|
175
148
|
const version = 'local';
|
176
|
-
const refs = assetInfos.map((assetInfo) => `kapeta://${assetInfo.metadata.name}:${version}`);
|
177
|
-
|
149
|
+
const refs = assetInfos.map((assetInfo) => (0, utils_1.normalizeKapetaUri)(`kapeta://${assetInfo.metadata.name}:${version}`));
|
150
|
+
refs.forEach((ref) => {
|
151
|
+
const key = toKey(ref);
|
152
|
+
cacheManager_1.cacheManager.remove(key);
|
153
|
+
});
|
154
|
+
definitionsManager_1.definitionsManager.clearCache();
|
178
155
|
return this.getAssets().filter((a) => refs.some((ref) => compareRefs(ref, a.ref)));
|
179
156
|
}
|
180
157
|
async unregisterAsset(ref) {
|
@@ -182,7 +159,9 @@ class AssetManager {
|
|
182
159
|
if (!asset) {
|
183
160
|
throw new Error('Asset does not exists: ' + ref);
|
184
161
|
}
|
185
|
-
|
162
|
+
const key = toKey(ref);
|
163
|
+
cacheManager_1.cacheManager.remove(key);
|
164
|
+
definitionsManager_1.definitionsManager.clearCache();
|
186
165
|
await nodejs_registry_utils_1.Actions.uninstall(new progressListener_1.ProgressListener(), [asset.ref]);
|
187
166
|
}
|
188
167
|
async installAsset(ref) {
|
@@ -192,7 +171,23 @@ class AssetManager {
|
|
192
171
|
}
|
193
172
|
const uri = (0, nodejs_utils_1.parseKapetaUri)(ref);
|
194
173
|
console.log('Installing %s', ref);
|
174
|
+
const key = toKey(ref);
|
175
|
+
cacheManager_1.cacheManager.remove(key);
|
176
|
+
definitionsManager_1.definitionsManager.clearCache();
|
195
177
|
return await repositoryManager_1.repositoryManager.ensureAsset(uri.handle, uri.name, uri.version, false);
|
196
178
|
}
|
179
|
+
maybeGenerateCode(ref, ymlPath, block) {
|
180
|
+
ref = (0, utils_1.normalizeKapetaUri)(ref);
|
181
|
+
if (codeGeneratorManager_1.codeGeneratorManager.canGenerateCode(block)) {
|
182
|
+
const assetTitle = block.metadata.title ? block.metadata.title : (0, nodejs_utils_1.parseKapetaUri)(block.metadata.name).name;
|
183
|
+
taskManager_1.taskManager.add(`codegen:${ref}`, async () => {
|
184
|
+
await codeGeneratorManager_1.codeGeneratorManager.generate(ymlPath, block);
|
185
|
+
}, {
|
186
|
+
name: `Generating code for ${assetTitle}`,
|
187
|
+
});
|
188
|
+
return true;
|
189
|
+
}
|
190
|
+
return false;
|
191
|
+
}
|
197
192
|
}
|
198
193
|
exports.assetManager = new AssetManager();
|
@@ -63,7 +63,7 @@ router.post('/create', async (req, res) => {
|
|
63
63
|
}
|
64
64
|
const content = parseBody(req);
|
65
65
|
try {
|
66
|
-
const assets = await assetManager_1.assetManager.createAsset(req.query.path, content);
|
66
|
+
const assets = await assetManager_1.assetManager.createAsset(req.query.path, content, 'user');
|
67
67
|
res.status(200).send(assets);
|
68
68
|
}
|
69
69
|
catch (err) {
|
@@ -81,7 +81,7 @@ router.put('/update', async (req, res) => {
|
|
81
81
|
}
|
82
82
|
const content = parseBody(req);
|
83
83
|
try {
|
84
|
-
await assetManager_1.assetManager.updateAsset(req.query.ref, content);
|
84
|
+
await assetManager_1.assetManager.updateAsset(req.query.ref, content, 'user');
|
85
85
|
res.sendStatus(204);
|
86
86
|
}
|
87
87
|
catch (err) {
|
@@ -0,0 +1,16 @@
|
|
1
|
+
export interface CacheEntry<T = any> {
|
2
|
+
expires: number;
|
3
|
+
data: T;
|
4
|
+
}
|
5
|
+
export declare class CacheManager {
|
6
|
+
private cache;
|
7
|
+
flush(): void;
|
8
|
+
doCached<T>(key: string, getter: () => T, ttl?: number): T;
|
9
|
+
get<T>(key: string): T | undefined;
|
10
|
+
set<T>(key: string, data: T, ttl?: number): void;
|
11
|
+
has(key: string): boolean;
|
12
|
+
remove(key: string): number;
|
13
|
+
removePrefix(key: string): void;
|
14
|
+
}
|
15
|
+
export declare const cacheManager: CacheManager;
|
16
|
+
export declare const doCached: <T>(key: string, getter: () => T, ttl?: number) => T;
|
@@ -0,0 +1,47 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
exports.doCached = exports.cacheManager = exports.CacheManager = void 0;
|
7
|
+
const node_cache_1 = __importDefault(require("node-cache"));
|
8
|
+
const DEFAULT_CACHE_TTL = 60 * 1000; // 1 min
|
9
|
+
class CacheManager {
|
10
|
+
cache = new node_cache_1.default();
|
11
|
+
flush() {
|
12
|
+
this.cache.flushAll();
|
13
|
+
}
|
14
|
+
doCached(key, getter, ttl = DEFAULT_CACHE_TTL) {
|
15
|
+
const data = this.cache.get(key);
|
16
|
+
if (data !== undefined) {
|
17
|
+
return data;
|
18
|
+
}
|
19
|
+
const result = getter();
|
20
|
+
this.cache.set(key, result, ttl);
|
21
|
+
return result;
|
22
|
+
}
|
23
|
+
get(key) {
|
24
|
+
return this.cache.get(key);
|
25
|
+
}
|
26
|
+
set(key, data, ttl = DEFAULT_CACHE_TTL) {
|
27
|
+
this.cache.set(key, data, ttl);
|
28
|
+
}
|
29
|
+
has(key) {
|
30
|
+
return this.cache.has(key);
|
31
|
+
}
|
32
|
+
remove(key) {
|
33
|
+
return this.cache.del(key);
|
34
|
+
}
|
35
|
+
removePrefix(key) {
|
36
|
+
const keys = this.cache.keys();
|
37
|
+
for (const k of keys) {
|
38
|
+
if (k.startsWith(key)) {
|
39
|
+
this.remove(k);
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
}
|
44
|
+
exports.CacheManager = CacheManager;
|
45
|
+
exports.cacheManager = new CacheManager();
|
46
|
+
const doCached = (key, getter, ttl = DEFAULT_CACHE_TTL) => exports.cacheManager.doCached(key, getter, ttl);
|
47
|
+
exports.doCached = doCached;
|
@@ -1,13 +1,12 @@
|
|
1
1
|
import { DefinitionInfo } from '@kapeta/local-cluster-config';
|
2
2
|
declare class DefinitionsManager {
|
3
|
-
private
|
4
|
-
private
|
5
|
-
clearCache(): void;
|
6
|
-
private doCached;
|
3
|
+
private getHash;
|
4
|
+
private getFullKey;
|
7
5
|
getDefinitions(kindFilter?: string | string[]): DefinitionInfo[];
|
8
6
|
exists(ref: string): boolean;
|
9
7
|
getProviderDefinitions(): DefinitionInfo[];
|
10
8
|
getDefinition(ref: string): DefinitionInfo | undefined;
|
9
|
+
clearCache(): void;
|
11
10
|
}
|
12
11
|
export declare const definitionsManager: DefinitionsManager;
|
13
12
|
export {};
|
@@ -6,10 +6,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.definitionsManager = void 0;
|
7
7
|
const local_cluster_config_1 = __importDefault(require("@kapeta/local-cluster-config"));
|
8
8
|
const nodejs_utils_1 = require("@kapeta/nodejs-utils");
|
9
|
-
const
|
9
|
+
const cacheManager_1 = require("./cacheManager");
|
10
10
|
class DefinitionsManager {
|
11
|
-
|
12
|
-
getKey(kindFilter) {
|
11
|
+
getHash(kindFilter) {
|
13
12
|
if (kindFilter) {
|
14
13
|
if (Array.isArray(kindFilter)) {
|
15
14
|
return kindFilter.join(',');
|
@@ -18,31 +17,18 @@ class DefinitionsManager {
|
|
18
17
|
}
|
19
18
|
return 'none';
|
20
19
|
}
|
21
|
-
|
22
|
-
this.
|
23
|
-
}
|
24
|
-
doCached(key, getter) {
|
25
|
-
if (this.cache[key]) {
|
26
|
-
if (this.cache[key].expires > Date.now()) {
|
27
|
-
return this.cache[key].definitions;
|
28
|
-
}
|
29
|
-
delete this.cache[key];
|
30
|
-
}
|
31
|
-
this.cache[key] = {
|
32
|
-
expires: Date.now() + CACHE_TTL,
|
33
|
-
definitions: getter(),
|
34
|
-
};
|
35
|
-
return this.cache[key].definitions;
|
20
|
+
getFullKey(kindFilter) {
|
21
|
+
return `definitionsManager:${this.getHash(kindFilter)}`;
|
36
22
|
}
|
37
23
|
getDefinitions(kindFilter) {
|
38
|
-
const key = this.
|
39
|
-
return
|
24
|
+
const key = this.getFullKey(kindFilter);
|
25
|
+
return (0, cacheManager_1.doCached)(key, () => local_cluster_config_1.default.getDefinitions(kindFilter));
|
40
26
|
}
|
41
27
|
exists(ref) {
|
42
28
|
return !!this.getDefinition(ref);
|
43
29
|
}
|
44
30
|
getProviderDefinitions() {
|
45
|
-
return
|
31
|
+
return (0, cacheManager_1.doCached)('providers', () => local_cluster_config_1.default.getProviderDefinitions());
|
46
32
|
}
|
47
33
|
getDefinition(ref) {
|
48
34
|
const uri = (0, nodejs_utils_1.parseKapetaUri)(ref);
|
@@ -53,5 +39,8 @@ class DefinitionsManager {
|
|
53
39
|
return (0, nodejs_utils_1.parseKapetaUri)(`${d.definition.metadata.name}:${d.version}`).id === uri.id;
|
54
40
|
});
|
55
41
|
}
|
42
|
+
clearCache() {
|
43
|
+
cacheManager_1.cacheManager.removePrefix('definitionsManager:');
|
44
|
+
}
|
56
45
|
}
|
57
46
|
exports.definitionsManager = new DefinitionsManager();
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import { Task } from './taskManager';
|
2
|
+
import { SourceOfChange } from './types';
|
2
3
|
declare class RepositoryManager {
|
3
4
|
private _registryService;
|
4
5
|
private _cache;
|
@@ -6,8 +7,12 @@ declare class RepositoryManager {
|
|
6
7
|
constructor();
|
7
8
|
listenForChanges(): void;
|
8
9
|
stopListening(): Promise<void>;
|
9
|
-
|
10
|
-
|
10
|
+
/**
|
11
|
+
* Setting the source of change helps us know
|
12
|
+
* how to react to changes in the UI.
|
13
|
+
*/
|
14
|
+
setSourceOfChangeFor(file: string, source: SourceOfChange): Promise<void>;
|
15
|
+
clearSourceOfChangeFor(file: string): Promise<void>;
|
11
16
|
ensureDefaultProviders(): void;
|
12
17
|
private _install;
|
13
18
|
ensureAsset(handle: string, name: string, version: string, wait?: boolean): Promise<undefined | Task[]>;
|
@@ -12,11 +12,7 @@ const taskManager_1 = require("./taskManager");
|
|
12
12
|
const utils_1 = require("./utils/utils");
|
13
13
|
const progressListener_1 = require("./progressListener");
|
14
14
|
const RepositoryWatcher_1 = require("./RepositoryWatcher");
|
15
|
-
const
|
16
|
-
function clearAllCaches() {
|
17
|
-
definitionsManager_1.definitionsManager.clearCache();
|
18
|
-
assetManager_1.assetManager.clearCache();
|
19
|
-
}
|
15
|
+
const cacheManager_1 = require("./cacheManager");
|
20
16
|
const EVENT_DEFAULT_PROVIDERS_START = 'default-providers-start';
|
21
17
|
const EVENT_DEFAULT_PROVIDERS_END = 'default-providers-end';
|
22
18
|
const DEFAULT_PROVIDERS = [
|
@@ -50,11 +46,15 @@ class RepositoryManager {
|
|
50
46
|
async stopListening() {
|
51
47
|
return this.watcher.unwatch();
|
52
48
|
}
|
53
|
-
|
54
|
-
|
49
|
+
/**
|
50
|
+
* Setting the source of change helps us know
|
51
|
+
* how to react to changes in the UI.
|
52
|
+
*/
|
53
|
+
setSourceOfChangeFor(file, source) {
|
54
|
+
return this.watcher.setSourceOfChangeFor(file, source);
|
55
55
|
}
|
56
|
-
|
57
|
-
return this.watcher.
|
56
|
+
clearSourceOfChangeFor(file) {
|
57
|
+
return this.watcher.clearSourceOfChangeFor(file);
|
58
58
|
}
|
59
59
|
ensureDefaultProviders() {
|
60
60
|
socketManager_1.socketManager.emitGlobal(EVENT_DEFAULT_PROVIDERS_START, { providers: DEFAULT_PROVIDERS });
|
@@ -85,7 +85,7 @@ class RepositoryManager {
|
|
85
85
|
console.error(`Failed to install asset: ${ref}`, e);
|
86
86
|
throw e;
|
87
87
|
}
|
88
|
-
|
88
|
+
cacheManager_1.cacheManager.flush();
|
89
89
|
//console.log(`Asset installed: ${ref}`);
|
90
90
|
};
|
91
91
|
};
|
package/dist/cjs/src/types.d.ts
CHANGED
@@ -8,6 +8,8 @@ export type StringMap = {
|
|
8
8
|
export type AnyMap = {
|
9
9
|
[key: string]: any;
|
10
10
|
};
|
11
|
+
export type SourceOfChange = 'user' | 'filesystem';
|
12
|
+
export type WatchEventName = 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir';
|
11
13
|
export type LogLevel = 'ERROR' | 'WARN' | 'INFO' | 'DEBUG' | 'TRACE' | 'FATAL';
|
12
14
|
export type LogSource = 'stdout' | 'stderr';
|
13
15
|
export type EnvironmentType = 'docker' | 'process';
|
@@ -1,15 +1,16 @@
|
|
1
|
+
import { SourceOfChange } from './types';
|
1
2
|
export declare class RepositoryWatcher {
|
2
3
|
private watcher?;
|
3
4
|
private disabled;
|
4
5
|
private readonly baseDir;
|
5
6
|
private allDefinitions;
|
6
7
|
private symbolicLinks;
|
7
|
-
private
|
8
|
+
private sourceOfChange;
|
8
9
|
constructor();
|
9
10
|
setDisabled(disabled: boolean): void;
|
10
11
|
watch(): void;
|
11
|
-
|
12
|
-
|
12
|
+
setSourceOfChangeFor(file: string, source: SourceOfChange): Promise<void>;
|
13
|
+
clearSourceOfChangeFor(file: string): Promise<void>;
|
13
14
|
unwatch(): Promise<void>;
|
14
15
|
private getAssetIdentity;
|
15
16
|
private handleFileChange;
|