@theia/plugin-ext 1.77.0-next.57 → 1.77.0-next.63
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/common/plugin-protocol.d.ts +9 -0
- package/lib/common/plugin-protocol.d.ts.map +1 -1
- package/lib/common/plugin-protocol.js +19 -1
- package/lib/common/plugin-protocol.js.map +1 -1
- package/lib/main/browser/main-file-system-event-service.d.ts +1 -22
- package/lib/main/browser/main-file-system-event-service.d.ts.map +1 -1
- package/lib/main/browser/main-file-system-event-service.js +2 -48
- package/lib/main/browser/main-file-system-event-service.js.map +1 -1
- package/lib/main/browser/view/plugin-view-registry.d.ts.map +1 -1
- package/lib/main/browser/view/plugin-view-registry.js +11 -4
- package/lib/main/browser/view/plugin-view-registry.js.map +1 -1
- package/lib/main/browser/view/plugin-view-registry.spec.js +69 -0
- package/lib/main/browser/view/plugin-view-registry.spec.js.map +1 -1
- package/lib/main/node/plugin-deployer-impl.d.ts.map +1 -1
- package/lib/main/node/plugin-deployer-impl.js +6 -1
- package/lib/main/node/plugin-deployer-impl.js.map +1 -1
- package/lib/main/node/plugin-deployer-impl.spec.d.ts +2 -0
- package/lib/main/node/plugin-deployer-impl.spec.d.ts.map +1 -0
- package/lib/main/node/plugin-deployer-impl.spec.js +66 -0
- package/lib/main/node/plugin-deployer-impl.spec.js.map +1 -0
- package/package.json +32 -32
- package/src/common/plugin-protocol.ts +18 -0
- package/src/main/browser/main-file-system-event-service.ts +2 -49
- package/src/main/browser/view/plugin-view-registry.spec.ts +92 -0
- package/src/main/browser/view/plugin-view-registry.ts +15 -5
- package/src/main/node/plugin-deployer-impl.spec.ts +75 -0
- package/src/main/node/plugin-deployer-impl.ts +7 -2
- package/lib/main/browser/main-file-system-event-service.spec.d.ts +0 -2
- package/lib/main/browser/main-file-system-event-service.spec.d.ts.map +0 -1
- package/lib/main/browser/main-file-system-event-service.spec.js +0 -101
- package/lib/main/browser/main-file-system-event-service.spec.js.map +0 -1
- package/src/main/browser/main-file-system-event-service.spec.ts +0 -125
|
@@ -22,7 +22,8 @@ import {
|
|
|
22
22
|
PluginDeployerResolver, PluginDeployerFileHandler, PluginDeployerDirectoryHandler,
|
|
23
23
|
PluginDeployerEntry, PluginDeployer, PluginDeployerParticipant, PluginDeployerStartContext,
|
|
24
24
|
PluginDeployerResolverInit,
|
|
25
|
-
PluginDeployerEntryType, PluginDeployerHandler, PluginType, UnresolvedPluginEntry, PluginIdentifiers, PluginDeployOptions
|
|
25
|
+
PluginDeployerEntryType, PluginDeployerHandler, PluginType, UnresolvedPluginEntry, PluginIdentifiers, PluginDeployOptions,
|
|
26
|
+
DuplicateExtensionError
|
|
26
27
|
} from '../../common/plugin-protocol';
|
|
27
28
|
import { PluginDeployerEntryImpl } from './plugin-deployer-entry-impl';
|
|
28
29
|
import {
|
|
@@ -215,7 +216,11 @@ export class PluginDeployerImpl implements PluginDeployer {
|
|
|
215
216
|
}
|
|
216
217
|
}
|
|
217
218
|
} catch (e) {
|
|
218
|
-
|
|
219
|
+
if (DuplicateExtensionError.is(e)) {
|
|
220
|
+
this.logger.info(`Skipping '${entry.id}': ${e.message}`);
|
|
221
|
+
} else {
|
|
222
|
+
this.logger.error(`Failed to resolve plugins from '${entry.id}'`, e);
|
|
223
|
+
}
|
|
219
224
|
errors.push(e instanceof Error ? e : new Error(String(e)));
|
|
220
225
|
}
|
|
221
226
|
}));
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"main-file-system-event-service.spec.d.ts","sourceRoot":"","sources":["../../../src/main/browser/main-file-system-event-service.spec.ts"],"names":[],"mappings":""}
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// *****************************************************************************
|
|
3
|
-
// Copyright (C) 2026 Safi Seid-Ahmad, K2view and others.
|
|
4
|
-
//
|
|
5
|
-
// This program and the accompanying materials are made available under the
|
|
6
|
-
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
-
// http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
-
//
|
|
9
|
-
// This Source Code may also be made available under the following Secondary
|
|
10
|
-
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
11
|
-
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
12
|
-
// with the GNU Classpath Exception which is available at
|
|
13
|
-
// https://www.gnu.org/software/classpath/license.html.
|
|
14
|
-
//
|
|
15
|
-
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
|
-
// *****************************************************************************
|
|
17
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
const tslib_1 = require("tslib");
|
|
19
|
-
const jsdom_1 = require("@theia/core/lib/browser/test/jsdom");
|
|
20
|
-
const disableJSDOM = (0, jsdom_1.enableJSDOM)();
|
|
21
|
-
const frontend_application_config_provider_1 = require("@theia/core/lib/browser/frontend-application-config-provider");
|
|
22
|
-
frontend_application_config_provider_1.FrontendApplicationConfigProvider.set({});
|
|
23
|
-
const assert = tslib_1.__importStar(require("assert"));
|
|
24
|
-
const core_1 = require("@theia/core");
|
|
25
|
-
const disposable_1 = require("@theia/core/lib/common/disposable");
|
|
26
|
-
const main_file_system_event_service_1 = require("./main-file-system-event-service");
|
|
27
|
-
disableJSDOM();
|
|
28
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
29
|
-
// A language server (e.g. `redhat.java` / JDT-LS) registers a watcher rooted at the PARENT of the
|
|
30
|
-
// workspace folder - `RelativePattern(parentDir, folderName)` - purely to detect deletion of the
|
|
31
|
-
// workspace folder itself. The pattern has no globstar, so `ensureWatching` sends it as a
|
|
32
|
-
// NON-recursive `$watch` on `parentDir`. Theia's backend ignores the `recursive` flag and always
|
|
33
|
-
// watches recursively, so this turns into a recursive crawl of every sibling subtree under the
|
|
34
|
-
// parent - thousands of inodes the workspace does not own - which can exhaust the OS file-watch
|
|
35
|
-
// budget. `files.watcherExclude` cannot bound it because the root is outside the workspace.
|
|
36
|
-
//
|
|
37
|
-
// These tests pin the fix: a non-recursive watch rooted at a strict ancestor of a workspace root is
|
|
38
|
-
// not registered, while watches on/inside the workspace and explicit recursive requests are
|
|
39
|
-
// untouched.
|
|
40
|
-
describe('MainFileSystemEventService ancestor-of-workspace watch handling', () => {
|
|
41
|
-
function componentsFor(path) {
|
|
42
|
-
return { scheme: 'file', authority: '', path, query: '', fragment: '' };
|
|
43
|
-
}
|
|
44
|
-
function createService(rootUris, watchCalls) {
|
|
45
|
-
const fileService = {
|
|
46
|
-
onDidFilesChange: () => disposable_1.Disposable.NULL,
|
|
47
|
-
onDidRunUserOperation: () => disposable_1.Disposable.NULL,
|
|
48
|
-
addFileOperationParticipant: () => disposable_1.Disposable.NULL,
|
|
49
|
-
watch: (resource) => {
|
|
50
|
-
watchCalls.push(resource);
|
|
51
|
-
return disposable_1.Disposable.NULL;
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
const workspaceService = { tryGetRoots: () => rootUris.map(uri => ({ resource: new core_1.URI(uri) })) };
|
|
55
|
-
const rpc = { getProxy: () => ({}) };
|
|
56
|
-
return new main_file_system_event_service_1.MainFileSystemEventService(rpc, {}, fileService, workspaceService);
|
|
57
|
-
}
|
|
58
|
-
it('skips a non-recursive watch rooted at a strict ancestor of a workspace root', () => {
|
|
59
|
-
const watchCalls = [];
|
|
60
|
-
const service = createService(['file:///projects/my-app'], watchCalls);
|
|
61
|
-
service.$watch(1, componentsFor('/projects'), { recursive: false, excludes: [] });
|
|
62
|
-
assert.strictEqual(watchCalls.length, 0, 'ancestor-of-workspace watch must not be registered');
|
|
63
|
-
});
|
|
64
|
-
it('still registers a non-recursive watch on the workspace root itself', () => {
|
|
65
|
-
const watchCalls = [];
|
|
66
|
-
const service = createService(['file:///projects/my-app'], watchCalls);
|
|
67
|
-
service.$watch(1, componentsFor('/projects/my-app'), { recursive: false, excludes: [] });
|
|
68
|
-
assert.strictEqual(watchCalls.length, 1);
|
|
69
|
-
});
|
|
70
|
-
it('still registers a non-recursive watch on an outer root that is itself the parent of another root', () => {
|
|
71
|
-
const watchCalls = [];
|
|
72
|
-
// Multi-root workspace where `/projects` is a root AND the parent of the `/projects/my-app` root.
|
|
73
|
-
// The outer root is explicitly opened by the user, so its watch must not be dropped as an
|
|
74
|
-
// "ancestor of the workspace".
|
|
75
|
-
const service = createService(['file:///projects', 'file:///projects/my-app'], watchCalls);
|
|
76
|
-
service.$watch(1, componentsFor('/projects'), { recursive: false, excludes: [] });
|
|
77
|
-
assert.strictEqual(watchCalls.length, 1, 'a folder that is itself a workspace root must be watched, even if it is an ancestor of another root');
|
|
78
|
-
});
|
|
79
|
-
it('still registers a non-recursive watch inside the workspace', () => {
|
|
80
|
-
const watchCalls = [];
|
|
81
|
-
const service = createService(['file:///projects/my-app'], watchCalls);
|
|
82
|
-
service.$watch(1, componentsFor('/projects/my-app/src'), { recursive: false, excludes: [] });
|
|
83
|
-
assert.strictEqual(watchCalls.length, 1);
|
|
84
|
-
});
|
|
85
|
-
it('does not skip an explicit recursive watch on an ancestor (honored as requested)', () => {
|
|
86
|
-
const watchCalls = [];
|
|
87
|
-
const service = createService(['file:///projects/my-app'], watchCalls);
|
|
88
|
-
service.$watch(1, componentsFor('/projects'), { recursive: true, excludes: [] });
|
|
89
|
-
assert.strictEqual(watchCalls.length, 1);
|
|
90
|
-
});
|
|
91
|
-
it('frees the session for a skipped watch so $unwatch and re-watch do not throw', () => {
|
|
92
|
-
const watchCalls = [];
|
|
93
|
-
const service = createService(['file:///projects/my-app'], watchCalls);
|
|
94
|
-
service.$watch(1, componentsFor('/projects'), { recursive: false, excludes: [] });
|
|
95
|
-
service.$unwatch(1);
|
|
96
|
-
// Re-using the same session id must not throw "already a watch request".
|
|
97
|
-
service.$watch(1, componentsFor('/projects'), { recursive: false, excludes: [] });
|
|
98
|
-
assert.strictEqual(watchCalls.length, 0);
|
|
99
|
-
});
|
|
100
|
-
});
|
|
101
|
-
//# sourceMappingURL=main-file-system-event-service.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"main-file-system-event-service.spec.js","sourceRoot":"","sources":["../../../src/main/browser/main-file-system-event-service.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
// *****************************************************************************
|
|
2
|
-
// Copyright (C) 2026 Safi Seid-Ahmad, K2view and others.
|
|
3
|
-
//
|
|
4
|
-
// This program and the accompanying materials are made available under the
|
|
5
|
-
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
-
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
-
//
|
|
8
|
-
// This Source Code may also be made available under the following Secondary
|
|
9
|
-
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
-
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
-
// with the GNU Classpath Exception which is available at
|
|
12
|
-
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
-
//
|
|
14
|
-
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
-
// *****************************************************************************
|
|
16
|
-
|
|
17
|
-
import { enableJSDOM } from '@theia/core/lib/browser/test/jsdom';
|
|
18
|
-
const disableJSDOM = enableJSDOM();
|
|
19
|
-
|
|
20
|
-
import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider';
|
|
21
|
-
FrontendApplicationConfigProvider.set({});
|
|
22
|
-
|
|
23
|
-
import * as assert from 'assert';
|
|
24
|
-
import { URI } from '@theia/core';
|
|
25
|
-
import { Disposable } from '@theia/core/lib/common/disposable';
|
|
26
|
-
import { UriComponents } from '../../common/uri-components';
|
|
27
|
-
import { MainFileSystemEventService } from './main-file-system-event-service';
|
|
28
|
-
|
|
29
|
-
disableJSDOM();
|
|
30
|
-
|
|
31
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
32
|
-
|
|
33
|
-
// A language server (e.g. `redhat.java` / JDT-LS) registers a watcher rooted at the PARENT of the
|
|
34
|
-
// workspace folder - `RelativePattern(parentDir, folderName)` - purely to detect deletion of the
|
|
35
|
-
// workspace folder itself. The pattern has no globstar, so `ensureWatching` sends it as a
|
|
36
|
-
// NON-recursive `$watch` on `parentDir`. Theia's backend ignores the `recursive` flag and always
|
|
37
|
-
// watches recursively, so this turns into a recursive crawl of every sibling subtree under the
|
|
38
|
-
// parent - thousands of inodes the workspace does not own - which can exhaust the OS file-watch
|
|
39
|
-
// budget. `files.watcherExclude` cannot bound it because the root is outside the workspace.
|
|
40
|
-
//
|
|
41
|
-
// These tests pin the fix: a non-recursive watch rooted at a strict ancestor of a workspace root is
|
|
42
|
-
// not registered, while watches on/inside the workspace and explicit recursive requests are
|
|
43
|
-
// untouched.
|
|
44
|
-
describe('MainFileSystemEventService ancestor-of-workspace watch handling', () => {
|
|
45
|
-
|
|
46
|
-
function componentsFor(path: string): UriComponents {
|
|
47
|
-
return { scheme: 'file', authority: '', path, query: '', fragment: '' };
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function createService(rootUris: string[], watchCalls: UriComponents[]): MainFileSystemEventService {
|
|
51
|
-
const fileService: any = {
|
|
52
|
-
onDidFilesChange: () => Disposable.NULL,
|
|
53
|
-
onDidRunUserOperation: () => Disposable.NULL,
|
|
54
|
-
addFileOperationParticipant: () => Disposable.NULL,
|
|
55
|
-
watch: (resource: UriComponents) => {
|
|
56
|
-
watchCalls.push(resource);
|
|
57
|
-
return Disposable.NULL;
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
const workspaceService: any = { tryGetRoots: () => rootUris.map(uri => ({ resource: new URI(uri) })) };
|
|
61
|
-
const rpc: any = { getProxy: () => ({}) };
|
|
62
|
-
return new MainFileSystemEventService(rpc, {} as any, fileService, workspaceService);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
it('skips a non-recursive watch rooted at a strict ancestor of a workspace root', () => {
|
|
66
|
-
const watchCalls: UriComponents[] = [];
|
|
67
|
-
const service = createService(['file:///projects/my-app'], watchCalls);
|
|
68
|
-
|
|
69
|
-
service.$watch(1, componentsFor('/projects'), { recursive: false, excludes: [] });
|
|
70
|
-
|
|
71
|
-
assert.strictEqual(watchCalls.length, 0, 'ancestor-of-workspace watch must not be registered');
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it('still registers a non-recursive watch on the workspace root itself', () => {
|
|
75
|
-
const watchCalls: UriComponents[] = [];
|
|
76
|
-
const service = createService(['file:///projects/my-app'], watchCalls);
|
|
77
|
-
|
|
78
|
-
service.$watch(1, componentsFor('/projects/my-app'), { recursive: false, excludes: [] });
|
|
79
|
-
|
|
80
|
-
assert.strictEqual(watchCalls.length, 1);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it('still registers a non-recursive watch on an outer root that is itself the parent of another root', () => {
|
|
84
|
-
const watchCalls: UriComponents[] = [];
|
|
85
|
-
// Multi-root workspace where `/projects` is a root AND the parent of the `/projects/my-app` root.
|
|
86
|
-
// The outer root is explicitly opened by the user, so its watch must not be dropped as an
|
|
87
|
-
// "ancestor of the workspace".
|
|
88
|
-
const service = createService(['file:///projects', 'file:///projects/my-app'], watchCalls);
|
|
89
|
-
|
|
90
|
-
service.$watch(1, componentsFor('/projects'), { recursive: false, excludes: [] });
|
|
91
|
-
|
|
92
|
-
assert.strictEqual(watchCalls.length, 1, 'a folder that is itself a workspace root must be watched, even if it is an ancestor of another root');
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it('still registers a non-recursive watch inside the workspace', () => {
|
|
96
|
-
const watchCalls: UriComponents[] = [];
|
|
97
|
-
const service = createService(['file:///projects/my-app'], watchCalls);
|
|
98
|
-
|
|
99
|
-
service.$watch(1, componentsFor('/projects/my-app/src'), { recursive: false, excludes: [] });
|
|
100
|
-
|
|
101
|
-
assert.strictEqual(watchCalls.length, 1);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it('does not skip an explicit recursive watch on an ancestor (honored as requested)', () => {
|
|
105
|
-
const watchCalls: UriComponents[] = [];
|
|
106
|
-
const service = createService(['file:///projects/my-app'], watchCalls);
|
|
107
|
-
|
|
108
|
-
service.$watch(1, componentsFor('/projects'), { recursive: true, excludes: [] });
|
|
109
|
-
|
|
110
|
-
assert.strictEqual(watchCalls.length, 1);
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it('frees the session for a skipped watch so $unwatch and re-watch do not throw', () => {
|
|
114
|
-
const watchCalls: UriComponents[] = [];
|
|
115
|
-
const service = createService(['file:///projects/my-app'], watchCalls);
|
|
116
|
-
|
|
117
|
-
service.$watch(1, componentsFor('/projects'), { recursive: false, excludes: [] });
|
|
118
|
-
service.$unwatch(1);
|
|
119
|
-
// Re-using the same session id must not throw "already a watch request".
|
|
120
|
-
service.$watch(1, componentsFor('/projects'), { recursive: false, excludes: [] });
|
|
121
|
-
|
|
122
|
-
assert.strictEqual(watchCalls.length, 0);
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
});
|