@kapeta/local-cluster-service 0.15.3 → 0.16.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/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [0.16.0](https://github.com/kapetacom/local-cluster-service/compare/v0.15.3...v0.16.0) (2023-08-11)
2
+
3
+
4
+ ### Features
5
+
6
+ * Use chokidar lib for watching for changes on disk ([#60](https://github.com/kapetacom/local-cluster-service/issues/60)) ([f2af855](https://github.com/kapetacom/local-cluster-service/commit/f2af85554fc2a23133ce27a4f8989cabdea097d7))
7
+
1
8
  ## [0.15.3](https://github.com/kapetacom/local-cluster-service/compare/v0.15.2...v0.15.3) (2023-08-10)
2
9
 
3
10
 
@@ -0,0 +1,22 @@
1
+ export declare class RepositoryWatcher {
2
+ private watcher?;
3
+ private disabled;
4
+ private readonly baseDir;
5
+ private allDefinitions;
6
+ private symbolicLinks;
7
+ private ignoredFiles;
8
+ constructor();
9
+ setDisabled(disabled: boolean): void;
10
+ watch(): void;
11
+ ignoreChangesFor(file: string): Promise<void>;
12
+ resumeChangedFor(file: string): Promise<void>;
13
+ unwatch(): Promise<void>;
14
+ private getAssetIdentity;
15
+ private handleFileChange;
16
+ private checkForChange;
17
+ private exists;
18
+ private removeSymlinkTarget;
19
+ private updateSymlinkTarget;
20
+ private addSymlinkTarget;
21
+ private ignoreFile;
22
+ }
@@ -0,0 +1,273 @@
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.RepositoryWatcher = void 0;
7
+ const chokidar_1 = __importDefault(require("chokidar"));
8
+ const local_cluster_config_1 = __importDefault(require("@kapeta/local-cluster-config"));
9
+ const fs_extra_1 = __importDefault(require("fs-extra"));
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ const yaml_1 = __importDefault(require("yaml"));
12
+ const nodejs_utils_1 = require("@kapeta/nodejs-utils");
13
+ const lodash_1 = __importDefault(require("lodash"));
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
+ }
21
+ const KAPETA_YML_RX = /^kapeta.ya?ml$/;
22
+ class RepositoryWatcher {
23
+ watcher;
24
+ disabled = false;
25
+ baseDir;
26
+ allDefinitions = [];
27
+ symbolicLinks = {};
28
+ ignoredFiles = new Set();
29
+ constructor() {
30
+ this.baseDir = local_cluster_config_1.default.getRepositoryBasedir();
31
+ }
32
+ setDisabled(disabled) {
33
+ this.disabled = disabled;
34
+ }
35
+ watch() {
36
+ if (!fs_extra_1.default.existsSync(this.baseDir)) {
37
+ fs_extra_1.default.mkdirpSync(this.baseDir);
38
+ }
39
+ this.allDefinitions = local_cluster_config_1.default.getDefinitions();
40
+ try {
41
+ this.watcher = chokidar_1.default.watch(this.baseDir, {
42
+ followSymlinks: false,
43
+ ignorePermissionErrors: true,
44
+ disableGlobbing: true,
45
+ persistent: true,
46
+ depth: 2,
47
+ ignored: (path) => this.ignoreFile(path),
48
+ });
49
+ this.watcher.on('all', this.handleFileChange.bind(this));
50
+ this.watcher.on('error', (error) => {
51
+ console.log('Error watching repository', error);
52
+ });
53
+ this.watcher.on('ready', () => {
54
+ console.log('Watching local repository for provider changes: %s', this.baseDir);
55
+ });
56
+ }
57
+ catch (e) {
58
+ // Fallback to run without watch mode due to potential platform issues.
59
+ // https://nodejs.org/docs/latest/api/fs.html#caveats
60
+ console.log('Unable to watch for changes. Changes to assets will not update automatically.', e);
61
+ return;
62
+ }
63
+ }
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);
69
+ }
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);
76
+ }
77
+ }
78
+ async unwatch() {
79
+ if (!this.watcher) {
80
+ return;
81
+ }
82
+ this.symbolicLinks = {};
83
+ await this.watcher.close();
84
+ this.watcher = undefined;
85
+ }
86
+ async getAssetIdentity(path) {
87
+ const baseName = node_path_1.default.basename(path);
88
+ let handle, name, version;
89
+ if (path.startsWith(this.baseDir)) {
90
+ const relativePath = node_path_1.default.relative(this.baseDir, path);
91
+ // Inside the repo we can use the path to determine the handle, name and version
92
+ [handle, name, version] = relativePath.split(/\//g);
93
+ if (!handle || !name || !version) {
94
+ // Do nothing with this
95
+ return;
96
+ }
97
+ return {
98
+ handle,
99
+ name,
100
+ version,
101
+ };
102
+ }
103
+ if (!KAPETA_YML_RX.test(baseName)) {
104
+ // Do nothing with this
105
+ return;
106
+ }
107
+ // Outside the repo we need to use the file content to determine the handle, name
108
+ // Version is always 'local'
109
+ version = 'local';
110
+ try {
111
+ const definition = yaml_1.default.parse((await fs_extra_1.default.readFile(path)).toString());
112
+ const uri = (0, nodejs_utils_1.parseKapetaUri)(definition.metadata.name);
113
+ handle = uri.handle;
114
+ name = uri.name;
115
+ return {
116
+ handle,
117
+ name,
118
+ version,
119
+ };
120
+ }
121
+ catch (e) {
122
+ // Ignore issues in the YML file
123
+ return;
124
+ }
125
+ }
126
+ async handleFileChange(eventName, path) {
127
+ if (!path) {
128
+ return;
129
+ }
130
+ if (this.ignoredFiles.has(path)) {
131
+ return;
132
+ }
133
+ //console.log('File changed', eventName, path);
134
+ const assetIdentity = await this.getAssetIdentity(path);
135
+ if (!assetIdentity) {
136
+ return;
137
+ }
138
+ if (this.disabled) {
139
+ return;
140
+ }
141
+ // If this is false it's because we're watching a symlink target
142
+ const withinRepo = path.startsWith(this.baseDir);
143
+ if (withinRepo && assetIdentity.version === 'local' && path.endsWith('/local')) {
144
+ // This is likely a symlink target
145
+ if (eventName === 'add') {
146
+ //console.log('Checking if we should add symlink target', handle, name, version, path);
147
+ await this.addSymlinkTarget(path);
148
+ }
149
+ if (eventName === 'unlink') {
150
+ await this.removeSymlinkTarget(path);
151
+ }
152
+ if (eventName === 'change') {
153
+ await this.updateSymlinkTarget(path);
154
+ }
155
+ }
156
+ await this.checkForChange(assetIdentity);
157
+ }
158
+ async checkForChange(assetIdentity) {
159
+ const ymlPath = node_path_1.default.join(this.baseDir, assetIdentity.handle, assetIdentity.name, assetIdentity.version, 'kapeta.yml');
160
+ const newDefinitions = local_cluster_config_1.default.getDefinitions();
161
+ const newDefinition = newDefinitions.find((d) => d.ymlPath === ymlPath);
162
+ let currentDefinition = this.allDefinitions.find((d) => d.ymlPath === ymlPath);
163
+ const ymlExists = await this.exists(ymlPath);
164
+ let type;
165
+ if (ymlExists) {
166
+ if (currentDefinition) {
167
+ if (newDefinition && lodash_1.default.isEqual(currentDefinition, newDefinition)) {
168
+ //Definition was not changed
169
+ return;
170
+ }
171
+ type = 'updated';
172
+ }
173
+ else if (newDefinition) {
174
+ type = 'added';
175
+ currentDefinition = newDefinition;
176
+ }
177
+ else {
178
+ //Other definition was added / updated - ignore
179
+ return;
180
+ }
181
+ }
182
+ else {
183
+ if (currentDefinition) {
184
+ const ref = (0, nodejs_utils_1.parseKapetaUri)(`${currentDefinition.definition.metadata.name}:${currentDefinition.version}`).id;
185
+ //Something was removed
186
+ type = 'removed';
187
+ }
188
+ else {
189
+ //Other definition was removed - ignore
190
+ return;
191
+ }
192
+ }
193
+ const payload = {
194
+ type,
195
+ definition: newDefinition?.definition ?? currentDefinition?.definition,
196
+ asset: assetIdentity,
197
+ };
198
+ this.allDefinitions = newDefinitions;
199
+ //console.log('Asset changed', payload);
200
+ socketManager_1.socketManager.emitGlobal('asset-change', payload);
201
+ clearAllCaches();
202
+ }
203
+ async exists(path) {
204
+ try {
205
+ await fs_extra_1.default.access(path);
206
+ return true;
207
+ }
208
+ catch (e) {
209
+ return false;
210
+ }
211
+ }
212
+ async removeSymlinkTarget(path) {
213
+ if (this.symbolicLinks[path]) {
214
+ //console.log('Unwatching symlink target %s => %s', path, this.symbolicLinks[path]);
215
+ this.watcher?.unwatch(this.symbolicLinks[path]);
216
+ delete this.symbolicLinks[path];
217
+ }
218
+ }
219
+ async updateSymlinkTarget(path) {
220
+ if (this.symbolicLinks[path]) {
221
+ //console.log('Updating symlink target %s => %s', path, this.symbolicLinks[path]);
222
+ this.watcher?.unwatch(this.symbolicLinks[path]);
223
+ delete this.symbolicLinks[path];
224
+ await this.addSymlinkTarget(path);
225
+ }
226
+ }
227
+ async addSymlinkTarget(path) {
228
+ try {
229
+ // Make sure we're not watching the symlink target
230
+ await this.removeSymlinkTarget(path);
231
+ const stat = await fs_extra_1.default.lstat(path);
232
+ if (stat.isSymbolicLink()) {
233
+ const realPath = `${await fs_extra_1.default.realpath(path)}/kapeta.yml`;
234
+ if (await this.exists(realPath)) {
235
+ //console.log('Watching symlink target %s => %s', path, realPath);
236
+ this.watcher?.add(realPath);
237
+ this.symbolicLinks[path] = realPath;
238
+ }
239
+ }
240
+ }
241
+ catch (e) {
242
+ // Ignore
243
+ console.warn('Failed to check local symlink target', e);
244
+ }
245
+ }
246
+ ignoreFile(path) {
247
+ if (!path.startsWith(this.baseDir)) {
248
+ return false;
249
+ }
250
+ if (path.includes('/node_modules/')) {
251
+ return true;
252
+ }
253
+ const filename = node_path_1.default.basename(path);
254
+ if (filename.startsWith('.')) {
255
+ return true;
256
+ }
257
+ const relativePath = node_path_1.default.relative(this.baseDir, path).split(node_path_1.default.sep);
258
+ try {
259
+ if (fs_extra_1.default.statSync(path).isDirectory()) {
260
+ if (relativePath.length > 3) {
261
+ return true;
262
+ }
263
+ return false;
264
+ }
265
+ }
266
+ catch (e) {
267
+ // Didn't exist - dont ignore
268
+ return false;
269
+ }
270
+ return !/^kapeta\.ya?ml$/.test(filename);
271
+ }
272
+ }
273
+ exports.RepositoryWatcher = RepositoryWatcher;
@@ -5,7 +5,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.assetManager = void 0;
7
7
  const node_path_1 = __importDefault(require("node:path"));
8
- const node_fs_1 = __importDefault(require("node:fs"));
9
8
  const fs_extra_1 = __importDefault(require("fs-extra"));
10
9
  const yaml_1 = __importDefault(require("yaml"));
11
10
  const node_cache_1 = __importDefault(require("node-cache"));
@@ -17,6 +16,10 @@ const nodejs_registry_utils_1 = require("@kapeta/nodejs-registry-utils");
17
16
  const definitionsManager_1 = require("./definitionsManager");
18
17
  const utils_1 = require("./utils/utils");
19
18
  const taskManager_1 = require("./taskManager");
19
+ function clearAllCaches() {
20
+ definitionsManager_1.definitionsManager.clearCache();
21
+ exports.assetManager.clearCache();
22
+ }
20
23
  function enrichAsset(asset) {
21
24
  return {
22
25
  ref: `kapeta://${asset.definition.metadata.name}:${asset.version}`,
@@ -103,19 +106,16 @@ class AssetManager {
103
106
  return asset;
104
107
  }
105
108
  async createAsset(path, yaml) {
106
- if (node_fs_1.default.existsSync(path)) {
109
+ if (await fs_extra_1.default.pathExists(path)) {
107
110
  throw new Error('File already exists: ' + path);
108
111
  }
109
112
  const dirName = node_path_1.default.dirname(path);
110
- if (!node_fs_1.default.existsSync(dirName)) {
111
- fs_extra_1.default.mkdirpSync(dirName);
113
+ if (!(await fs_extra_1.default.pathExists(dirName))) {
114
+ await fs_extra_1.default.mkdirp(dirName);
112
115
  }
113
- console.log('Wrote to ' + path);
114
- node_fs_1.default.writeFileSync(path, yaml_1.default.stringify(yaml));
116
+ await fs_extra_1.default.writeFile(path, yaml_1.default.stringify(yaml));
115
117
  const asset = await this.importFile(path);
116
- console.log('Imported');
117
- this.cache.flushAll();
118
- definitionsManager_1.definitionsManager.clearCache();
118
+ clearAllCaches();
119
119
  const ref = `kapeta://${yaml.metadata.name}:local`;
120
120
  this.maybeGenerateCode(ref, path, yaml);
121
121
  return asset;
@@ -131,11 +131,23 @@ class AssetManager {
131
131
  if (!asset.ymlPath) {
132
132
  throw new Error('Attempted to update corrupted asset: ' + ref);
133
133
  }
134
- console.log('Wrote to ' + asset.ymlPath);
135
- node_fs_1.default.writeFileSync(asset.ymlPath, yaml_1.default.stringify(yaml));
136
- this.cache.flushAll();
137
- definitionsManager_1.definitionsManager.clearCache();
138
- this.maybeGenerateCode(asset.ref, asset.ymlPath, yaml);
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
+ }
139
151
  }
140
152
  maybeGenerateCode(ref, ymlPath, block) {
141
153
  ref = (0, utils_1.normalizeKapetaUri)(ref);
@@ -154,14 +166,15 @@ class AssetManager {
154
166
  if (filePath.startsWith('file://')) {
155
167
  filePath = filePath.substring('file://'.length);
156
168
  }
157
- if (!node_fs_1.default.existsSync(filePath)) {
169
+ if (!(await fs_extra_1.default.pathExists(filePath))) {
158
170
  throw new Error('File not found: ' + filePath);
159
171
  }
160
- const assetInfos = yaml_1.default.parseAllDocuments(node_fs_1.default.readFileSync(filePath).toString()).map((doc) => doc.toJSON());
172
+ const content = await fs_extra_1.default.readFile(filePath);
173
+ const assetInfos = yaml_1.default.parseAllDocuments(content.toString()).map((doc) => doc.toJSON());
161
174
  await nodejs_registry_utils_1.Actions.link(new progressListener_1.ProgressListener(), node_path_1.default.dirname(filePath));
162
175
  const version = 'local';
163
176
  const refs = assetInfos.map((assetInfo) => `kapeta://${assetInfo.metadata.name}:${version}`);
164
- this.cache.flushAll();
177
+ clearAllCaches();
165
178
  return this.getAssets().filter((a) => refs.some((ref) => compareRefs(ref, a.ref)));
166
179
  }
167
180
  async unregisterAsset(ref) {
@@ -169,7 +182,7 @@ class AssetManager {
169
182
  if (!asset) {
170
183
  throw new Error('Asset does not exists: ' + ref);
171
184
  }
172
- this.cache.flushAll();
185
+ clearAllCaches();
173
186
  await nodejs_registry_utils_1.Actions.uninstall(new progressListener_1.ProgressListener(), [asset.ref]);
174
187
  }
175
188
  async installAsset(ref) {
@@ -57,7 +57,10 @@ class InstanceManager {
57
57
  return [];
58
58
  }
59
59
  const plan = planInfo.definition;
60
- const instanceIds = plan.spec.blocks.map((block) => block.id);
60
+ if (!plan?.spec?.blocks) {
61
+ return [];
62
+ }
63
+ const instanceIds = plan.spec?.blocks?.map((block) => block.id) || [];
61
64
  return this._instances.filter((instance) => instance.systemId === systemId && instanceIds.includes(instance.instanceId));
62
65
  }
63
66
  getInstance(systemId, instanceId) {
@@ -1,13 +1,13 @@
1
1
  import { Task } from './taskManager';
2
2
  declare class RepositoryManager {
3
- private changeEventsEnabled;
4
3
  private _registryService;
5
4
  private _cache;
6
- private watcher?;
5
+ private watcher;
7
6
  constructor();
8
- setChangeEventsEnabled(enabled: boolean): void;
9
7
  listenForChanges(): void;
10
- stopListening(): void;
8
+ stopListening(): Promise<void>;
9
+ ignoreChangesFor(file: string): Promise<void>;
10
+ resumeChangedFor(file: string): Promise<void>;
11
11
  ensureDefaultProviders(): void;
12
12
  private _install;
13
13
  ensureAsset(handle: string, name: string, version: string, wait?: boolean): Promise<undefined | Task[]>;
@@ -4,20 +4,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.repositoryManager = void 0;
7
- const node_fs_1 = __importDefault(require("node:fs"));
8
7
  const node_os_1 = __importDefault(require("node:os"));
9
- const node_path_1 = __importDefault(require("node:path"));
10
- const recursive_watch_1 = __importDefault(require("recursive-watch"));
11
- const fs_extra_1 = __importDefault(require("fs-extra"));
12
- const local_cluster_config_1 = __importDefault(require("@kapeta/local-cluster-config"));
13
- const nodejs_utils_1 = require("@kapeta/nodejs-utils");
14
8
  const socketManager_1 = require("./socketManager");
15
9
  const nodejs_registry_utils_1 = require("@kapeta/nodejs-registry-utils");
16
10
  const definitionsManager_1 = require("./definitionsManager");
17
11
  const taskManager_1 = require("./taskManager");
18
12
  const utils_1 = require("./utils/utils");
19
- const assetManager_1 = require("./assetManager");
20
13
  const progressListener_1 = require("./progressListener");
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
+ }
21
20
  const EVENT_DEFAULT_PROVIDERS_START = 'default-providers-start';
22
21
  const EVENT_DEFAULT_PROVIDERS_END = 'default-providers-end';
23
22
  const DEFAULT_PROVIDERS = [
@@ -36,92 +35,26 @@ const DEFAULT_PROVIDERS = [
36
35
  ];
37
36
  const INSTALL_ATTEMPTED = {};
38
37
  class RepositoryManager {
39
- changeEventsEnabled;
40
38
  _registryService;
41
39
  _cache;
42
40
  watcher;
43
41
  constructor() {
44
- this.changeEventsEnabled = true;
45
- this.listenForChanges();
46
42
  this._registryService = new nodejs_registry_utils_1.RegistryService(nodejs_registry_utils_1.Config.data.registry.url);
47
43
  this._cache = {};
48
- }
49
- setChangeEventsEnabled(enabled) {
50
- this.changeEventsEnabled = enabled;
44
+ this.watcher = new RepositoryWatcher_1.RepositoryWatcher();
45
+ this.listenForChanges();
51
46
  }
52
47
  listenForChanges() {
53
- const baseDir = local_cluster_config_1.default.getRepositoryBasedir();
54
- if (!node_fs_1.default.existsSync(baseDir)) {
55
- fs_extra_1.default.mkdirpSync(baseDir);
56
- }
57
- let allDefinitions = local_cluster_config_1.default.getDefinitions();
58
- console.log('Watching local repository for provider changes: %s', baseDir);
59
- try {
60
- this.watcher = (0, recursive_watch_1.default)(baseDir, (filename) => {
61
- if (!filename) {
62
- return;
63
- }
64
- const [handle, name, version] = filename.toString().split(/\//g);
65
- if (!name || !version) {
66
- return;
67
- }
68
- if (!this.changeEventsEnabled) {
69
- return;
70
- }
71
- const ymlPath = node_path_1.default.join(baseDir, handle, name, version, 'kapeta.yml');
72
- const newDefinitions = local_cluster_config_1.default.getDefinitions();
73
- const newDefinition = newDefinitions.find((d) => d.ymlPath === ymlPath);
74
- let currentDefinition = allDefinitions.find((d) => d.ymlPath === ymlPath);
75
- const ymlExists = node_fs_1.default.existsSync(ymlPath);
76
- let type;
77
- if (ymlExists) {
78
- if (currentDefinition) {
79
- type = 'updated';
80
- }
81
- else if (newDefinition) {
82
- type = 'added';
83
- currentDefinition = newDefinition;
84
- }
85
- else {
86
- //Other definition was added / updated - ignore
87
- return;
88
- }
89
- }
90
- else {
91
- if (currentDefinition) {
92
- const ref = (0, nodejs_utils_1.parseKapetaUri)(`${currentDefinition.definition.metadata.name}:${currentDefinition.version}`).id;
93
- delete INSTALL_ATTEMPTED[ref];
94
- //Something was removed
95
- type = 'removed';
96
- }
97
- else {
98
- //Other definition was removed - ignore
99
- return;
100
- }
101
- }
102
- const payload = {
103
- type,
104
- definition: currentDefinition?.definition,
105
- asset: { handle, name, version },
106
- };
107
- allDefinitions = newDefinitions;
108
- socketManager_1.socketManager.emit(`assets`, 'changed', payload);
109
- definitionsManager_1.definitionsManager.clearCache();
110
- });
111
- }
112
- catch (e) {
113
- // Fallback to run without watch mode due to potential platform issues.
114
- // https://nodejs.org/docs/latest/api/fs.html#caveats
115
- console.log('Unable to watch for changes. Changes to assets will not update automatically.', e);
116
- return;
117
- }
48
+ this.watcher.watch();
118
49
  }
119
- stopListening() {
120
- if (!this.watcher) {
121
- return;
122
- }
123
- this.watcher();
124
- this.watcher = undefined;
50
+ async stopListening() {
51
+ return this.watcher.unwatch();
52
+ }
53
+ ignoreChangesFor(file) {
54
+ return this.watcher.ignoreChangesFor(file);
55
+ }
56
+ resumeChangedFor(file) {
57
+ return this.watcher.resumeChangedFor(file);
125
58
  }
126
59
  ensureDefaultProviders() {
127
60
  socketManager_1.socketManager.emitGlobal(EVENT_DEFAULT_PROVIDERS_START, { providers: DEFAULT_PROVIDERS });
@@ -146,19 +79,13 @@ class RepositoryManager {
146
79
  try {
147
80
  //We change to a temp dir to avoid issues with the current working directory
148
81
  process.chdir(node_os_1.default.tmpdir());
149
- //Disable change events while installing
150
- this.setChangeEventsEnabled(false);
151
82
  await nodejs_registry_utils_1.Actions.install(new progressListener_1.ProgressListener(), [ref], {});
152
83
  }
153
84
  catch (e) {
154
85
  console.error(`Failed to install asset: ${ref}`, e);
155
86
  throw e;
156
87
  }
157
- finally {
158
- this.setChangeEventsEnabled(true);
159
- }
160
- definitionsManager_1.definitionsManager.clearCache();
161
- assetManager_1.assetManager.clearCache();
88
+ clearAllCaches();
162
89
  //console.log(`Asset installed: ${ref}`);
163
90
  };
164
91
  };
@@ -0,0 +1,22 @@
1
+ export declare class RepositoryWatcher {
2
+ private watcher?;
3
+ private disabled;
4
+ private readonly baseDir;
5
+ private allDefinitions;
6
+ private symbolicLinks;
7
+ private ignoredFiles;
8
+ constructor();
9
+ setDisabled(disabled: boolean): void;
10
+ watch(): void;
11
+ ignoreChangesFor(file: string): Promise<void>;
12
+ resumeChangedFor(file: string): Promise<void>;
13
+ unwatch(): Promise<void>;
14
+ private getAssetIdentity;
15
+ private handleFileChange;
16
+ private checkForChange;
17
+ private exists;
18
+ private removeSymlinkTarget;
19
+ private updateSymlinkTarget;
20
+ private addSymlinkTarget;
21
+ private ignoreFile;
22
+ }