@opensumi/ide-file-service 3.7.1-next-1739439717.0 → 3.7.1-next-1739521933.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.
Files changed (44) hide show
  1. package/lib/browser/file-service-client.js +4 -4
  2. package/lib/browser/file-service-client.js.map +1 -1
  3. package/lib/browser/file-service-provider-client.d.ts +2 -2
  4. package/lib/browser/file-service-provider-client.d.ts.map +1 -1
  5. package/lib/browser/file-service-provider-client.js +2 -2
  6. package/lib/browser/file-service-provider-client.js.map +1 -1
  7. package/lib/common/files.d.ts +2 -2
  8. package/lib/common/files.d.ts.map +1 -1
  9. package/lib/common/watcher.d.ts +3 -2
  10. package/lib/common/watcher.d.ts.map +1 -1
  11. package/lib/common/watcher.js.map +1 -1
  12. package/lib/node/disk-file-system.provider.d.ts +3 -2
  13. package/lib/node/disk-file-system.provider.d.ts.map +1 -1
  14. package/lib/node/disk-file-system.provider.js +3 -2
  15. package/lib/node/disk-file-system.provider.js.map +1 -1
  16. package/lib/node/hosted/recursive/file-service-watcher.d.ts +14 -13
  17. package/lib/node/hosted/recursive/file-service-watcher.d.ts.map +1 -1
  18. package/lib/node/hosted/recursive/file-service-watcher.js +158 -97
  19. package/lib/node/hosted/recursive/file-service-watcher.js.map +1 -1
  20. package/lib/node/hosted/un-recursive/file-service-watcher.d.ts +5 -11
  21. package/lib/node/hosted/un-recursive/file-service-watcher.d.ts.map +1 -1
  22. package/lib/node/hosted/un-recursive/file-service-watcher.js +15 -31
  23. package/lib/node/hosted/un-recursive/file-service-watcher.js.map +1 -1
  24. package/lib/node/hosted/watcher.host.service.d.ts +7 -2
  25. package/lib/node/hosted/watcher.host.service.d.ts.map +1 -1
  26. package/lib/node/hosted/watcher.host.service.js +60 -28
  27. package/lib/node/hosted/watcher.host.service.js.map +1 -1
  28. package/lib/node/hosted/watcher.process.js +1 -1
  29. package/lib/node/hosted/watcher.process.js.map +1 -1
  30. package/lib/node/watcher-process-manager.d.ts +3 -2
  31. package/lib/node/watcher-process-manager.d.ts.map +1 -1
  32. package/lib/node/watcher-process-manager.js +4 -3
  33. package/lib/node/watcher-process-manager.js.map +1 -1
  34. package/package.json +9 -9
  35. package/src/browser/file-service-client.ts +4 -4
  36. package/src/browser/file-service-provider-client.ts +3 -2
  37. package/src/common/files.ts +2 -2
  38. package/src/common/watcher.ts +10 -3
  39. package/src/node/disk-file-system.provider.ts +8 -3
  40. package/src/node/hosted/recursive/file-service-watcher.ts +190 -108
  41. package/src/node/hosted/un-recursive/file-service-watcher.ts +22 -46
  42. package/src/node/hosted/watcher.host.service.ts +100 -33
  43. package/src/node/hosted/watcher.process.ts +1 -1
  44. package/src/node/watcher-process-manager.ts +13 -5
@@ -1,20 +1,45 @@
1
1
  import { SumiConnectionMultiplexer } from '@opensumi/ide-connection';
2
- import { DidFilesChangedParams } from '@opensumi/ide-core-common';
2
+ import {
3
+ DidFilesChangedParams,
4
+ Disposable,
5
+ DisposableCollection,
6
+ FileUri,
7
+ IDisposable,
8
+ RecursiveWatcherBackend,
9
+ } from '@opensumi/ide-core-common';
3
10
  import { defaultFilesWatcherExcludes, flattenExcludes } from '@opensumi/ide-core-common/lib/preferences/file-watch';
4
11
  import { URI, Uri, UriComponents } from '@opensumi/ide-utils/lib/uri';
5
12
 
6
13
  import { IWatcherHostService, WatcherProcessManagerProxy, WatcherServiceProxy } from '../../common/watcher';
7
14
  import { IWatcher } from '../disk-file-system.provider';
8
15
 
9
- import { FileSystemWatcherServer } from './recursive/file-service-watcher';
16
+ import { RecursiveFileSystemWatcher } from './recursive/file-service-watcher';
10
17
  import { UnRecursiveFileSystemWatcher } from './un-recursive/file-service-watcher';
11
18
  import { WatcherProcessLogger } from './watch-process-log';
12
19
 
20
+ const watcherPlaceHolder = {
21
+ disposable: {
22
+ dispose: () => {},
23
+ },
24
+ handlers: [],
25
+ };
26
+
13
27
  export class WatcherHostServiceImpl implements IWatcherHostService {
28
+ private static WATCHER_SEQUENCE = 1;
29
+
30
+ private WATCHER_HANDLERS = new Map<
31
+ number,
32
+ {
33
+ path: string;
34
+ handlers: any;
35
+ disposable: IDisposable;
36
+ }
37
+ >();
38
+
14
39
  /**
15
40
  * recursive file system watcher
16
41
  */
17
- private recursiveFileSystemWatcher?: FileSystemWatcherServer;
42
+ private recursiveFileSystemWatcher?: RecursiveFileSystemWatcher;
18
43
 
19
44
  /**
20
45
  * unrecursive file system watcher
@@ -27,7 +52,11 @@ export class WatcherHostServiceImpl implements IWatcherHostService {
27
52
 
28
53
  private watchedDirs: Set<string> = new Set();
29
54
 
30
- constructor(private rpcProtocol: SumiConnectionMultiplexer, private logger: WatcherProcessLogger) {
55
+ constructor(
56
+ private rpcProtocol: SumiConnectionMultiplexer,
57
+ private logger: WatcherProcessLogger,
58
+ private backend: RecursiveWatcherBackend,
59
+ ) {
31
60
  this.rpcProtocol.set(WatcherServiceProxy, this);
32
61
  this.defaultExcludes = flattenExcludes(defaultFilesWatcherExcludes);
33
62
  this.initWatcherServer(this.defaultExcludes);
@@ -48,18 +77,19 @@ export class WatcherHostServiceImpl implements IWatcherHostService {
48
77
 
49
78
  // rewatch
50
79
  for (const [_uri, { options, disposable }] of this.watcherCollection) {
51
- this.doWatch(Uri.parse(_uri), options);
52
80
  this.logger.log('rewatch file changes: ', _uri, ' recursive: ', options?.recursive);
53
81
  disposable.dispose();
82
+ this.watcherCollection.delete(_uri);
83
+ this.doWatch(Uri.parse(_uri), options);
54
84
  }
55
85
  }
56
86
 
57
- this.recursiveFileSystemWatcher = new FileSystemWatcherServer(excludes, this.logger);
87
+ this.recursiveFileSystemWatcher = new RecursiveFileSystemWatcher(excludes, this.logger, this.backend);
58
88
  this.unrecursiveFileSystemWatcher = new UnRecursiveFileSystemWatcher(this.logger);
59
89
 
60
90
  const watcherClient = {
61
91
  onDidFilesChanged: (events: DidFilesChangedParams) => {
62
- this.logger.log('watcher server onDidFilesChanged: ', events);
92
+ this.logger.log('onDidFilesChanged: ', events);
63
93
  const proxy = this.rpcProtocol.getProxy(WatcherProcessManagerProxy);
64
94
  proxy.$onDidFilesChanged(events);
65
95
  },
@@ -69,47 +99,84 @@ export class WatcherHostServiceImpl implements IWatcherHostService {
69
99
  this.unrecursiveFileSystemWatcher.setClient(watcherClient);
70
100
  }
71
101
 
72
- private getWatcherServer(recursive?: boolean) {
73
- const useRecursiveServer = recursive;
74
- let watcherServer: FileSystemWatcherServer | UnRecursiveFileSystemWatcher;
102
+ checkIsAlreadyWatched(watcherPath: string): number | undefined {
103
+ for (const [watcherId, watcher] of this.WATCHER_HANDLERS) {
104
+ if (watcherPath === watcher.path) {
105
+ return watcherId;
106
+ }
107
+ }
108
+ }
109
+
110
+ private async doWatch(
111
+ uri: Uri,
112
+ options?: { excludes?: string[]; recursive?: boolean; pollingWatch?: boolean },
113
+ ): Promise<number> {
75
114
  this.initWatcherServer();
115
+ const basePath = FileUri.fsPath(uri.toString());
116
+ let watcherId = this.checkIsAlreadyWatched(basePath);
76
117
 
77
- if (useRecursiveServer) {
78
- watcherServer = this.recursiveFileSystemWatcher!;
79
- } else {
80
- watcherServer = this.unrecursiveFileSystemWatcher!;
118
+ if (watcherId) {
119
+ this.logger.log(uri.toString(), 'is already watched');
120
+ return watcherId;
81
121
  }
82
122
 
83
- return watcherServer;
84
- }
123
+ watcherId = WatcherHostServiceImpl.WATCHER_SEQUENCE++;
85
124
 
86
- private async doWatch(uri: Uri, options?: { excludes?: string[]; recursive?: boolean }): Promise<number> {
87
- const watcherServer = this.getWatcherServer(options?.recursive);
88
- if (!watcherServer) {
89
- return -1;
90
- }
125
+ this.WATCHER_HANDLERS.set(watcherId, {
126
+ ...watcherPlaceHolder,
127
+ path: basePath,
128
+ });
91
129
 
92
130
  this.logger.log('watch file changes: ', uri.toString(), ' recursive: ', options?.recursive);
93
131
 
94
132
  const mergedExcludes = new Set([...(options?.excludes ?? []), ...this.defaultExcludes]);
95
- const id = await watcherServer.watchFileChanges(uri.toString(), {
96
- excludes: Array.from(mergedExcludes),
97
- });
98
133
 
99
- this.watchedDirs.add(uri.toString());
134
+ const disposables = new DisposableCollection();
100
135
 
101
- const disposable = {
102
- dispose: () => {
103
- watcherServer.unwatchFileChanges(id);
136
+ await this.unrecursiveFileSystemWatcher!.watchFileChanges(uri.toString());
137
+
138
+ disposables.push(
139
+ Disposable.create(async () => {
140
+ this.unrecursiveFileSystemWatcher!.unwatchFileChanges(uri.toString());
141
+ this.logger.log('dispose unrecursive watcher: ', uri.toString());
104
142
  this.watchedDirs.delete(uri.toString());
105
- },
106
- };
143
+ this.WATCHER_HANDLERS.delete(watcherId);
144
+ }),
145
+ );
146
+
147
+ if (options?.recursive) {
148
+ this.logger.log('use recursive watcher for: ', uri.toString());
149
+ try {
150
+ await this.recursiveFileSystemWatcher!.watchFileChanges(uri.toString(), {
151
+ excludes: Array.from(mergedExcludes),
152
+ pollingWatch: options?.pollingWatch,
153
+ });
154
+
155
+ disposables.push(
156
+ Disposable.create(async () => {
157
+ this.logger.log('dispose recursive watcher: ', uri.toString());
158
+ this.recursiveFileSystemWatcher!.unwatchFileChanges(uri.toString());
159
+ this.watchedDirs.delete(uri.toString());
160
+ this.WATCHER_HANDLERS.delete(watcherId);
161
+ }),
162
+ );
163
+ } catch (error) {
164
+ // watch error or timeout
165
+ this.logger.error('watch error: ', error);
166
+ }
167
+ }
168
+
169
+ this.watcherCollection.set(uri.toString(), { id: watcherId, options, disposable: disposables });
170
+
171
+ this.watchedDirs.add(uri.toString());
107
172
 
108
- this.watcherCollection.set(uri.toString(), { id, options, disposable });
109
- return id;
173
+ return watcherId;
110
174
  }
111
175
 
112
- async $watch(uri: UriComponents, options?: { excludes?: string[]; recursive?: boolean }): Promise<number> {
176
+ async $watch(
177
+ uri: UriComponents,
178
+ options?: { excludes?: string[]; recursive?: boolean; pollingWatch?: boolean },
179
+ ): Promise<number> {
113
180
  const _uri = URI.revive(uri);
114
181
  return this.doWatch(_uri, options);
115
182
  }
@@ -37,7 +37,7 @@ async function initWatcherProcess() {
37
37
  });
38
38
 
39
39
  const logger = new WatcherProcessLogger(watcherInjector, initData.logDir, initData.logLevel);
40
- const watcherHostService = new WatcherHostServiceImpl(watcherProtocol, logger);
40
+ const watcherHostService = new WatcherHostServiceImpl(watcherProtocol, logger, initData.backend);
41
41
  watcherHostService.initWatcherServer();
42
42
  }
43
43
 
@@ -7,7 +7,11 @@ import { IRPCProtocol } from '@opensumi/ide-connection';
7
7
  import { NetSocketConnection } from '@opensumi/ide-connection/lib/common/connection/drivers/socket';
8
8
  import { SumiConnectionMultiplexer } from '@opensumi/ide-connection/lib/common/rpc/multiplexer';
9
9
  import { ILogServiceManager, SupportLogNamespace } from '@opensumi/ide-core-common/lib/log';
10
- import { DidFilesChangedParams, FileSystemWatcherClient } from '@opensumi/ide-core-common/lib/types/file-watch';
10
+ import {
11
+ DidFilesChangedParams,
12
+ FileSystemWatcherClient,
13
+ RecursiveWatcherBackend,
14
+ } from '@opensumi/ide-core-common/lib/types/file-watch';
11
15
  import { normalizedIpcHandlerPathAsync } from '@opensumi/ide-core-common/lib/utils/ipc';
12
16
  import { AppConfig, Deferred, ILogService, UriComponents } from '@opensumi/ide-core-node';
13
17
  import { process as processUtil } from '@opensumi/ide-utils';
@@ -110,7 +114,7 @@ export class WatcherProcessManagerImpl implements IWatcherProcessManager {
110
114
  );
111
115
  }
112
116
 
113
- private async createWatcherProcess(clientId: string, ipcHandlerPath: string) {
117
+ private async createWatcherProcess(clientId: string, ipcHandlerPath: string, backend?: RecursiveWatcherBackend) {
114
118
  const forkArgs = [
115
119
  `--${SUMI_WATCHER_PROCESS_SOCK_KEY}=${JSON.stringify({
116
120
  path: ipcHandlerPath,
@@ -118,6 +122,7 @@ export class WatcherProcessManagerImpl implements IWatcherProcessManager {
118
122
  `--${WATCHER_INIT_DATA_KEY}=${JSON.stringify({
119
123
  logDir: this.appConfig.logDir,
120
124
  logLevel: this.appConfig.logLevel,
125
+ backend,
121
126
  clientId,
122
127
  })}`,
123
128
  ];
@@ -136,14 +141,14 @@ export class WatcherProcessManagerImpl implements IWatcherProcessManager {
136
141
  return this.watcherProcess.pid;
137
142
  }
138
143
 
139
- async createProcess(clientId: string) {
144
+ async createProcess(clientId: string, backend?: RecursiveWatcherBackend) {
140
145
  this.logger.log('create watcher process for client: ', clientId);
141
146
  this.logger.log('appconfig watcherHost: ', this.watcherHost);
142
147
 
143
148
  const ipcHandlerPath = await this.getIPCHandlerPath('watcher_process');
144
149
  await this.createWatcherServer(clientId, ipcHandlerPath);
145
150
 
146
- const pid = await this.createWatcherProcess(clientId, ipcHandlerPath);
151
+ const pid = await this.createWatcherProcess(clientId, ipcHandlerPath, backend);
147
152
 
148
153
  return pid;
149
154
  }
@@ -158,7 +163,10 @@ export class WatcherProcessManagerImpl implements IWatcherProcessManager {
158
163
  }
159
164
  }
160
165
 
161
- async watch(uri: UriComponents, options?: { excludes?: string[]; recursive?: boolean }): Promise<number> {
166
+ async watch(
167
+ uri: UriComponents,
168
+ options?: { excludes?: string[]; recursive?: boolean; pollingWatch?: boolean },
169
+ ): Promise<number> {
162
170
  this.logger.log('Wait for watcher process ready...');
163
171
  await this._whenReadyDeferred.promise;
164
172
  this.logger.log('start watch: ', uri);