@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.
Files changed (36) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/src/RepositoryWatcher.d.ts +4 -3
  3. package/dist/cjs/src/RepositoryWatcher.js +29 -23
  4. package/dist/cjs/src/assetManager.d.ts +4 -6
  5. package/dist/cjs/src/assetManager.js +49 -54
  6. package/dist/cjs/src/assets/routes.js +2 -2
  7. package/dist/cjs/src/cacheManager.d.ts +16 -0
  8. package/dist/cjs/src/cacheManager.js +47 -0
  9. package/dist/cjs/src/definitionsManager.d.ts +3 -4
  10. package/dist/cjs/src/definitionsManager.js +10 -21
  11. package/dist/cjs/src/repositoryManager.d.ts +7 -2
  12. package/dist/cjs/src/repositoryManager.js +10 -10
  13. package/dist/cjs/src/types.d.ts +2 -0
  14. package/dist/cjs/src/utils/utils.js +1 -1
  15. package/dist/esm/src/RepositoryWatcher.d.ts +4 -3
  16. package/dist/esm/src/RepositoryWatcher.js +29 -23
  17. package/dist/esm/src/assetManager.d.ts +4 -6
  18. package/dist/esm/src/assetManager.js +49 -54
  19. package/dist/esm/src/assets/routes.js +2 -2
  20. package/dist/esm/src/cacheManager.d.ts +16 -0
  21. package/dist/esm/src/cacheManager.js +39 -0
  22. package/dist/esm/src/definitionsManager.d.ts +3 -4
  23. package/dist/esm/src/definitionsManager.js +10 -21
  24. package/dist/esm/src/repositoryManager.d.ts +7 -2
  25. package/dist/esm/src/repositoryManager.js +10 -10
  26. package/dist/esm/src/types.d.ts +2 -0
  27. package/dist/esm/src/utils/utils.js +1 -1
  28. package/package.json +1 -1
  29. package/src/RepositoryWatcher.ts +30 -26
  30. package/src/assetManager.ts +63 -60
  31. package/src/assets/routes.ts +2 -2
  32. package/src/cacheManager.ts +54 -0
  33. package/src/definitionsManager.ts +13 -33
  34. package/src/repositoryManager.ts +11 -12
  35. package/src/types.ts +2 -2
  36. 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 ignoredFiles;
8
+ private sourceOfChange;
8
9
  constructor();
9
10
  setDisabled(disabled: boolean): void;
10
11
  watch(): void;
11
- ignoreChangesFor(file: string): Promise<void>;
12
- resumeChangedFor(file: string): Promise<void>;
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 definitionsManager_1 = require("./definitionsManager");
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
- ignoredFiles = new Set();
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 ignoreChangesFor(file) {
65
- this.ignoredFiles.add(file);
66
- const realPath = await fs_extra_1.default.realpath(file);
67
- if (realPath !== file) {
68
- this.ignoredFiles.add(realPath);
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 resumeChangedFor(file) {
72
- this.ignoredFiles.delete(file);
73
- const realPath = await fs_extra_1.default.realpath(file);
74
- if (realPath !== file) {
75
- this.ignoredFiles.delete(realPath);
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
- await this.checkForChange(assetIdentity);
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
- clearAllCaches();
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
- function clearAllCaches() {
20
- definitionsManager_1.definitionsManager.clearCache();
21
- exports.assetManager.clearCache();
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 = `getAsset:${ref}`;
89
- if (!noCache && this.cache.has(cacheKey)) {
90
- return this.cache.get(cacheKey);
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
- this.cache.set(cacheKey, asset);
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
- clearAllCaches();
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
- const path = asset.ymlPath;
135
- try {
136
- await repositoryManager_1.repositoryManager.ignoreChangesFor(path);
137
- await fs_extra_1.default.writeFile(asset.ymlPath, yaml_1.default.stringify(yaml));
138
- console.log('Wrote to ' + asset.ymlPath);
139
- clearAllCaches();
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
- clearAllCaches();
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
- clearAllCaches();
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 cache;
4
- private getKey;
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 CACHE_TTL = 60 * 1000; // 1 min
9
+ const cacheManager_1 = require("./cacheManager");
10
10
  class DefinitionsManager {
11
- cache = {};
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
- clearCache() {
22
- this.cache = {};
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.getKey(kindFilter);
39
- return this.doCached(key, () => local_cluster_config_1.default.getDefinitions(kindFilter));
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 this.doCached('providers', () => local_cluster_config_1.default.getProviderDefinitions());
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
- ignoreChangesFor(file: string): Promise<void>;
10
- resumeChangedFor(file: string): Promise<void>;
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 assetManager_1 = require("./assetManager");
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
- ignoreChangesFor(file) {
54
- return this.watcher.ignoreChangesFor(file);
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
- resumeChangedFor(file) {
57
- return this.watcher.resumeChangedFor(file);
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
- clearAllCaches();
88
+ cacheManager_1.cacheManager.flush();
89
89
  //console.log(`Asset installed: ${ref}`);
90
90
  };
91
91
  };
@@ -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';
@@ -29,7 +29,7 @@ function readYML(path) {
29
29
  return yaml_1.default.parse(rawYaml.toString());
30
30
  }
31
31
  catch (err) {
32
- throw new Error('Failed to parse plan YAML: ' + err);
32
+ throw new Error(`Failed to parse plan YAML: ${err}`);
33
33
  }
34
34
  }
35
35
  exports.readYML = readYML;
@@ -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 ignoredFiles;
8
+ private sourceOfChange;
8
9
  constructor();
9
10
  setDisabled(disabled: boolean): void;
10
11
  watch(): void;
11
- ignoreChangesFor(file: string): Promise<void>;
12
- resumeChangedFor(file: string): Promise<void>;
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;