@theia/plugin-ext 1.76.0-next.7 → 1.77.0-next.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/lib/common/paths-util.d.ts.map +1 -1
- package/lib/common/paths-util.js +9 -2
- package/lib/common/paths-util.js.map +1 -1
- package/lib/common/paths-util.spec.d.ts +2 -0
- package/lib/common/paths-util.spec.d.ts.map +1 -0
- package/lib/common/paths-util.spec.js +42 -0
- package/lib/common/paths-util.spec.js.map +1 -0
- package/lib/common/plugin-api-rpc.d.ts +14 -0
- package/lib/common/plugin-api-rpc.d.ts.map +1 -1
- package/lib/common/plugin-api-rpc.js +1 -1
- package/lib/common/plugin-api-rpc.js.map +1 -1
- package/lib/common/plugin-protocol.d.ts +2 -2
- package/lib/common/plugin-protocol.d.ts.map +1 -1
- package/lib/common/plugin-protocol.js +2 -1
- package/lib/common/plugin-protocol.js.map +1 -1
- package/lib/hosted/browser/hosted-plugin.d.ts +2 -0
- package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
- package/lib/hosted/browser/hosted-plugin.js +9 -3
- package/lib/hosted/browser/hosted-plugin.js.map +1 -1
- package/lib/hosted/browser/worker/worker-main.js +22 -12
- package/lib/hosted/browser/worker/worker-main.js.map +1 -1
- package/lib/hosted/browser/worker/worker-plugin-module.d.ts.map +1 -1
- package/lib/hosted/browser/worker/worker-plugin-module.js +2 -0
- package/lib/hosted/browser/worker/worker-plugin-module.js.map +1 -1
- package/lib/hosted/browser-only/browser-only-hosted-plugin-server.d.ts +37 -0
- package/lib/hosted/browser-only/browser-only-hosted-plugin-server.d.ts.map +1 -0
- package/lib/hosted/browser-only/browser-only-hosted-plugin-server.js +107 -0
- package/lib/hosted/browser-only/browser-only-hosted-plugin-server.js.map +1 -0
- package/lib/hosted/browser-only/browser-only-hosted-plugin-server.spec.d.ts +2 -0
- package/lib/hosted/browser-only/browser-only-hosted-plugin-server.spec.d.ts.map +1 -0
- package/lib/hosted/browser-only/browser-only-hosted-plugin-server.spec.js +106 -0
- package/lib/hosted/browser-only/browser-only-hosted-plugin-server.spec.js.map +1 -0
- package/lib/hosted/browser-only/browser-only-plugin-file-system-provider.d.ts +38 -0
- package/lib/hosted/browser-only/browser-only-plugin-file-system-provider.d.ts.map +1 -0
- package/lib/hosted/browser-only/browser-only-plugin-file-system-provider.js +124 -0
- package/lib/hosted/browser-only/browser-only-plugin-file-system-provider.js.map +1 -0
- package/lib/hosted/browser-only/browser-only-plugin-file-system-provider.spec.d.ts +2 -0
- package/lib/hosted/browser-only/browser-only-plugin-file-system-provider.spec.d.ts.map +1 -0
- package/lib/hosted/browser-only/browser-only-plugin-file-system-provider.spec.js +137 -0
- package/lib/hosted/browser-only/browser-only-plugin-file-system-provider.spec.js.map +1 -0
- package/lib/hosted/browser-only/browser-only-plugin-paths-service.d.ts +43 -0
- package/lib/hosted/browser-only/browser-only-plugin-paths-service.d.ts.map +1 -0
- package/lib/hosted/browser-only/browser-only-plugin-paths-service.js +145 -0
- package/lib/hosted/browser-only/browser-only-plugin-paths-service.js.map +1 -0
- package/lib/hosted/browser-only/browser-only-plugin-paths-service.spec.d.ts +2 -0
- package/lib/hosted/browser-only/browser-only-plugin-paths-service.spec.d.ts.map +1 -0
- package/lib/hosted/browser-only/browser-only-plugin-paths-service.spec.js +165 -0
- package/lib/hosted/browser-only/browser-only-plugin-paths-service.spec.js.map +1 -0
- package/lib/hosted/browser-only/browser-only-plugin-server.d.ts +54 -0
- package/lib/hosted/browser-only/browser-only-plugin-server.d.ts.map +1 -0
- package/lib/hosted/browser-only/browser-only-plugin-server.js +155 -0
- package/lib/hosted/browser-only/browser-only-plugin-server.js.map +1 -0
- package/lib/hosted/browser-only/browser-only-plugin-server.spec.d.ts +2 -0
- package/lib/hosted/browser-only/browser-only-plugin-server.spec.d.ts.map +1 -0
- package/lib/hosted/browser-only/browser-only-plugin-server.spec.js +190 -0
- package/lib/hosted/browser-only/browser-only-plugin-server.spec.js.map +1 -0
- package/lib/hosted/browser-only/test/navigator-locks-test-util.d.ts +24 -0
- package/lib/hosted/browser-only/test/navigator-locks-test-util.d.ts.map +1 -0
- package/lib/hosted/browser-only/test/navigator-locks-test-util.js +46 -0
- package/lib/hosted/browser-only/test/navigator-locks-test-util.js.map +1 -0
- package/lib/hosted/common/hosted-plugin.d.ts +2 -2
- package/lib/hosted/common/hosted-plugin.d.ts.map +1 -1
- package/lib/hosted/common/hosted-plugin.js +2 -2
- package/lib/hosted/common/hosted-plugin.js.map +1 -1
- package/lib/hosted/node/plugin-host-module.d.ts.map +1 -1
- package/lib/hosted/node/plugin-host-module.js +2 -0
- package/lib/hosted/node/plugin-host-module.js.map +1 -1
- package/lib/hosted/node/plugin-host-rpc.d.ts +3 -0
- package/lib/hosted/node/plugin-host-rpc.d.ts.map +1 -1
- package/lib/hosted/node/plugin-host-rpc.js +9 -3
- package/lib/hosted/node/plugin-host-rpc.js.map +1 -1
- package/lib/main/browser/editors-and-documents-main.d.ts +7 -0
- package/lib/main/browser/editors-and-documents-main.d.ts.map +1 -1
- package/lib/main/browser/editors-and-documents-main.js +19 -9
- package/lib/main/browser/editors-and-documents-main.js.map +1 -1
- package/lib/main/browser/editors-and-documents-main.spec.d.ts +2 -0
- package/lib/main/browser/editors-and-documents-main.spec.d.ts.map +1 -0
- package/lib/main/browser/editors-and-documents-main.spec.js +117 -0
- package/lib/main/browser/editors-and-documents-main.spec.js.map +1 -0
- package/lib/main/browser/languages-main.d.ts +7 -0
- package/lib/main/browser/languages-main.d.ts.map +1 -1
- package/lib/main/browser/languages-main.js +31 -9
- package/lib/main/browser/languages-main.js.map +1 -1
- package/lib/main/browser/languages-main.spec.d.ts +2 -0
- package/lib/main/browser/languages-main.spec.d.ts.map +1 -0
- package/lib/main/browser/languages-main.spec.js +82 -0
- package/lib/main/browser/languages-main.spec.js.map +1 -0
- package/lib/main/browser/main-context.d.ts.map +1 -1
- package/lib/main/browser/main-context.js +3 -0
- package/lib/main/browser/main-context.js.map +1 -1
- package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts +5 -0
- package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts.map +1 -1
- package/lib/main/browser/menus/vscode-theia-menu-mappings.js +5 -0
- package/lib/main/browser/menus/vscode-theia-menu-mappings.js.map +1 -1
- package/lib/main/browser/plugin-ext-frontend-module.d.ts.map +1 -1
- package/lib/main/browser/plugin-ext-frontend-module.js +1 -0
- package/lib/main/browser/plugin-ext-frontend-module.js.map +1 -1
- package/lib/main/browser/plugin-icon-service.d.ts +6 -0
- package/lib/main/browser/plugin-icon-service.d.ts.map +1 -1
- package/lib/main/browser/plugin-icon-service.js +14 -2
- package/lib/main/browser/plugin-icon-service.js.map +1 -1
- package/lib/main/browser/plugin-icon-service.spec.d.ts +2 -0
- package/lib/main/browser/plugin-icon-service.spec.d.ts.map +1 -0
- package/lib/main/browser/plugin-icon-service.spec.js +83 -0
- package/lib/main/browser/plugin-icon-service.spec.js.map +1 -0
- package/lib/main/browser/plugin-icon-theme-service.d.ts.map +1 -1
- package/lib/main/browser/plugin-icon-theme-service.js +2 -1
- package/lib/main/browser/plugin-icon-theme-service.js.map +1 -1
- package/lib/main/browser/plugin-icon-theme-service.spec.d.ts +2 -0
- package/lib/main/browser/plugin-icon-theme-service.spec.d.ts.map +1 -0
- package/lib/main/browser/plugin-icon-theme-service.spec.js +91 -0
- package/lib/main/browser/plugin-icon-theme-service.spec.js.map +1 -0
- package/lib/main/browser/telemetry-main.d.ts +20 -0
- package/lib/main/browser/telemetry-main.d.ts.map +1 -0
- package/lib/main/browser/telemetry-main.js +43 -0
- package/lib/main/browser/telemetry-main.js.map +1 -0
- package/lib/main/browser/telemetry-main.spec.d.ts +2 -0
- package/lib/main/browser/telemetry-main.spec.d.ts.map +1 -0
- package/lib/main/browser/telemetry-main.spec.js +66 -0
- package/lib/main/browser/telemetry-main.spec.js.map +1 -0
- package/lib/main/browser/webview/webview-context-keys.d.ts +3 -2
- package/lib/main/browser/webview/webview-context-keys.d.ts.map +1 -1
- package/lib/main/browser/webview/webview-context-keys.js +16 -2
- package/lib/main/browser/webview/webview-context-keys.js.map +1 -1
- package/lib/main/browser/webview/webview-environment.d.ts.map +1 -1
- package/lib/main/browser/webview/webview-environment.js +2 -1
- package/lib/main/browser/webview/webview-environment.js.map +1 -1
- package/lib/main/common/paths/const.d.ts +13 -0
- package/lib/main/common/paths/const.d.ts.map +1 -0
- package/lib/main/common/paths/const.js +32 -0
- package/lib/main/common/paths/const.js.map +1 -0
- package/lib/main/node/paths/const.d.ts +5 -5
- package/lib/main/node/paths/const.d.ts.map +1 -1
- package/lib/main/node/paths/const.js +6 -6
- package/lib/main/node/paths/const.js.map +1 -1
- package/lib/main/node/paths/plugin-paths-service.js +1 -1
- package/lib/main/node/paths/plugin-paths-service.js.map +1 -1
- package/lib/main/node/plugin-cli-contribution.d.ts +2 -2
- package/lib/main/node/plugin-cli-contribution.d.ts.map +1 -1
- package/lib/main/node/plugin-cli-contribution.js +4 -3
- package/lib/main/node/plugin-cli-contribution.js.map +1 -1
- package/lib/main/node/plugins-key-value-storage.js +1 -1
- package/lib/main/node/plugins-key-value-storage.js.map +1 -1
- package/lib/main/node/resolvers/local-directory-plugin-deployer-resolver.d.ts +5 -0
- package/lib/main/node/resolvers/local-directory-plugin-deployer-resolver.d.ts.map +1 -1
- package/lib/main/node/resolvers/local-directory-plugin-deployer-resolver.js +12 -1
- package/lib/main/node/resolvers/local-directory-plugin-deployer-resolver.js.map +1 -1
- package/lib/main/node/resolvers/local-directory-plugin-deployer-resolver.spec.d.ts +2 -0
- package/lib/main/node/resolvers/local-directory-plugin-deployer-resolver.spec.d.ts.map +1 -0
- package/lib/main/node/resolvers/local-directory-plugin-deployer-resolver.spec.js +54 -0
- package/lib/main/node/resolvers/local-directory-plugin-deployer-resolver.spec.js.map +1 -0
- package/lib/plugin/plugin-context.d.ts +2 -1
- package/lib/plugin/plugin-context.d.ts.map +1 -1
- package/lib/plugin/plugin-context.js +2 -3
- package/lib/plugin/plugin-context.js.map +1 -1
- package/lib/plugin/plugin-manager.d.ts +2 -0
- package/lib/plugin/plugin-manager.d.ts.map +1 -1
- package/lib/plugin/plugin-manager.js +12 -1
- package/lib/plugin/plugin-manager.js.map +1 -1
- package/lib/plugin/relative-pattern.spec.d.ts +2 -0
- package/lib/plugin/relative-pattern.spec.d.ts.map +1 -0
- package/lib/plugin/relative-pattern.spec.js +51 -0
- package/lib/plugin/relative-pattern.spec.js.map +1 -0
- package/lib/plugin/telemetry-ext.d.ts +23 -7
- package/lib/plugin/telemetry-ext.d.ts.map +1 -1
- package/lib/plugin/telemetry-ext.js +60 -33
- package/lib/plugin/telemetry-ext.js.map +1 -1
- package/lib/plugin/telemetry-ext.spec.js +121 -16
- package/lib/plugin/telemetry-ext.spec.js.map +1 -1
- package/lib/plugin-ext-frontend-only-module.d.ts +4 -0
- package/lib/plugin-ext-frontend-only-module.d.ts.map +1 -0
- package/lib/plugin-ext-frontend-only-module.js +34 -0
- package/lib/plugin-ext-frontend-only-module.js.map +1 -0
- package/package.json +36 -32
- package/src/common/paths-util.spec.ts +47 -0
- package/src/common/paths-util.ts +11 -2
- package/src/common/plugin-api-rpc.ts +15 -1
- package/src/common/plugin-protocol.ts +2 -0
- package/src/hosted/browser/hosted-plugin.ts +9 -4
- package/src/hosted/browser/worker/worker-main.ts +23 -12
- package/src/hosted/browser/worker/worker-plugin-module.ts +2 -0
- package/src/hosted/browser-only/browser-only-hosted-plugin-server.spec.ts +133 -0
- package/src/hosted/browser-only/browser-only-hosted-plugin-server.ts +122 -0
- package/src/hosted/browser-only/browser-only-plugin-file-system-provider.spec.ts +178 -0
- package/src/hosted/browser-only/browser-only-plugin-file-system-provider.ts +129 -0
- package/src/hosted/browser-only/browser-only-plugin-paths-service.spec.ts +199 -0
- package/src/hosted/browser-only/browser-only-plugin-paths-service.ts +145 -0
- package/src/hosted/browser-only/browser-only-plugin-server.spec.ts +228 -0
- package/src/hosted/browser-only/browser-only-plugin-server.ts +165 -0
- package/src/hosted/browser-only/test/navigator-locks-test-util.ts +54 -0
- package/src/hosted/common/hosted-plugin.ts +4 -4
- package/src/hosted/node/plugin-host-module.ts +2 -0
- package/src/hosted/node/plugin-host-rpc.ts +10 -4
- package/src/main/browser/editors-and-documents-main.spec.ts +140 -0
- package/src/main/browser/editors-and-documents-main.ts +19 -7
- package/src/main/browser/languages-main.spec.ts +101 -0
- package/src/main/browser/languages-main.ts +31 -9
- package/src/main/browser/main-context.ts +4 -0
- package/src/main/browser/menus/vscode-theia-menu-mappings.ts +5 -0
- package/src/main/browser/plugin-ext-frontend-module.ts +2 -1
- package/src/main/browser/plugin-icon-service.spec.ts +101 -0
- package/src/main/browser/plugin-icon-service.ts +16 -3
- package/src/main/browser/plugin-icon-theme-service.spec.ts +103 -0
- package/src/main/browser/plugin-icon-theme-service.ts +2 -1
- package/src/main/browser/telemetry-main.spec.ts +77 -0
- package/src/main/browser/telemetry-main.ts +46 -0
- package/src/main/browser/webview/webview-context-keys.ts +20 -4
- package/src/main/browser/webview/webview-environment.ts +2 -1
- package/src/main/common/paths/const.ts +28 -0
- package/src/main/node/paths/const.ts +5 -5
- package/src/main/node/paths/plugin-paths-service.ts +1 -1
- package/src/main/node/plugin-cli-contribution.ts +4 -3
- package/src/main/node/plugins-key-value-storage.ts +1 -1
- package/src/main/node/resolvers/local-directory-plugin-deployer-resolver.spec.ts +61 -0
- package/src/main/node/resolvers/local-directory-plugin-deployer-resolver.ts +14 -1
- package/src/plugin/plugin-context.ts +3 -2
- package/src/plugin/plugin-manager.ts +11 -1
- package/src/plugin/relative-pattern.spec.ts +55 -0
- package/src/plugin/telemetry-ext.spec.ts +158 -17
- package/src/plugin/telemetry-ext.ts +63 -33
- package/src/plugin-ext-frontend-only-module.ts +34 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2026 Robert Jandow
|
|
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
|
+
exports.BrowserOnlyPluginPathsService = void 0;
|
|
19
|
+
const tslib_1 = require("tslib");
|
|
20
|
+
const inversify_1 = require("@theia/core/shared/inversify");
|
|
21
|
+
const core_1 = require("@theia/core");
|
|
22
|
+
const uri_1 = require("@theia/core/lib/common/uri");
|
|
23
|
+
const uuid_1 = require("@theia/core/lib/common/uuid");
|
|
24
|
+
const strings_1 = require("@theia/core/lib/common/strings");
|
|
25
|
+
const env_variables_1 = require("@theia/core/lib/common/env-variables");
|
|
26
|
+
const file_service_1 = require("@theia/filesystem/lib/browser/file-service");
|
|
27
|
+
const common_1 = require("@theia/workspace/lib/common");
|
|
28
|
+
const const_1 = require("../../main/common/paths/const");
|
|
29
|
+
/** Session folder name, e.g. `20181205T093828`, same format as the backend uses. */
|
|
30
|
+
const SESSION_TIMESTAMP_PATTERN = /^\d{8}T\d{6}$/;
|
|
31
|
+
/**
|
|
32
|
+
* Resolves plugin log and storage locations for a browser-only application, under the config
|
|
33
|
+
* directory, which lives on the same (browser-local) file system as the workspace.
|
|
34
|
+
*/
|
|
35
|
+
let BrowserOnlyPluginPathsService = class BrowserOnlyPluginPathsService {
|
|
36
|
+
constructor() {
|
|
37
|
+
/**
|
|
38
|
+
* Resolving re-hashes the workspace id and hits {@link FileService.createFolder}, and the plugin
|
|
39
|
+
* server asks for this on every workspace storage read/write. The roots are part of the key
|
|
40
|
+
* because an untitled workspace's id is derived from them.
|
|
41
|
+
*/
|
|
42
|
+
this.hostStoragePaths = new Map();
|
|
43
|
+
}
|
|
44
|
+
getHostLogPath() {
|
|
45
|
+
// cached: unlike the backend, where each call creates a new session folder, here one tab
|
|
46
|
+
// runs one session, and the plugin host may ask again on a later load cycle
|
|
47
|
+
return this.hostLogPath ??= this.resolveHostLogPath();
|
|
48
|
+
}
|
|
49
|
+
async resolveHostLogPath() {
|
|
50
|
+
const configDirUri = new uri_1.default(await this.envServer.getConfigDirUri());
|
|
51
|
+
const logsDirUri = configDirUri.resolve(const_1.PluginPaths.PLUGINS_LOGS_DIR);
|
|
52
|
+
const hostLogPath = await this.ensureDirectory(logsDirUri.resolve(this.generateTimeFolderName()).resolve('host'));
|
|
53
|
+
// as on the backend, we never wait for the cleanup
|
|
54
|
+
this.cleanUpOldLogs(logsDirUri).catch(error => this.logger.error('Failed to clean up old plugin log folders:', error));
|
|
55
|
+
return hostLogPath;
|
|
56
|
+
}
|
|
57
|
+
async getHostStoragePath(workspaceUri, rootUris) {
|
|
58
|
+
if (!workspaceUri) {
|
|
59
|
+
// no workspace, no place to store workspace state - same as the backend
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
// '\n' cannot appear in a URI, so it is safe as a separator between the workspace URI and its roots
|
|
63
|
+
const cacheKey = `${workspaceUri}\n${[...rootUris].sort().join('\n')}`;
|
|
64
|
+
let hostStoragePath = this.hostStoragePaths.get(cacheKey);
|
|
65
|
+
if (!hostStoragePath) {
|
|
66
|
+
hostStoragePath = this.resolveHostStoragePath(workspaceUri, rootUris);
|
|
67
|
+
this.hostStoragePaths.set(cacheKey, hostStoragePath);
|
|
68
|
+
// a transient failure (e.g. a flaky file system call) shouldn't poison the cache forever
|
|
69
|
+
hostStoragePath.catch(() => this.hostStoragePaths.delete(cacheKey));
|
|
70
|
+
}
|
|
71
|
+
return hostStoragePath;
|
|
72
|
+
}
|
|
73
|
+
async resolveHostStoragePath(workspaceUri, rootUris) {
|
|
74
|
+
const configDirUri = new uri_1.default(await this.envServer.getConfigDirUri());
|
|
75
|
+
const workspaceId = await this.buildWorkspaceId(configDirUri, workspaceUri, rootUris);
|
|
76
|
+
return this.ensureDirectory(configDirUri.resolve(const_1.PluginPaths.PLUGINS_WORKSPACE_STORAGE_DIR).resolve(workspaceId));
|
|
77
|
+
}
|
|
78
|
+
async buildWorkspaceId(configDirUri, workspaceUri, rootUris) {
|
|
79
|
+
if (this.untitledWorkspaceService.isUntitledWorkspace(new uri_1.default(workspaceUri), configDirUri)) {
|
|
80
|
+
// an untitled workspace is named anew in every session, so key its storage on the roots instead
|
|
81
|
+
return (0, uuid_1.hashValue)([...rootUris].sort().join(','));
|
|
82
|
+
}
|
|
83
|
+
return (0, uuid_1.hashValue)(workspaceUri);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Generate time folder name in format: YYYYMMDDTHHMMSS, for example: 20181205T093828
|
|
87
|
+
*/
|
|
88
|
+
generateTimeFolderName() {
|
|
89
|
+
const timeStamp = new Date().toISOString().replace(/[-:]|(\..*)/g, '');
|
|
90
|
+
// Helps ensure our timestamp generation logic is "valid".
|
|
91
|
+
// Changes to the timestamp structure may break old logs deletion logic.
|
|
92
|
+
if (!SESSION_TIMESTAMP_PATTERN.test(timeStamp)) {
|
|
93
|
+
this.logger.error(`Generated log folder name: "${timeStamp}" does not match expected pattern: ${SESSION_TIMESTAMP_PATTERN}`);
|
|
94
|
+
}
|
|
95
|
+
return timeStamp;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Keeps only the most recent {@link PluginPaths.DEFAULT_PLUGIN_MAX_SESSION_LOGS_FOLDERS}
|
|
99
|
+
* session folders under `logsDirUri`, so reloading doesn't fill up browser storage.
|
|
100
|
+
*/
|
|
101
|
+
async cleanUpOldLogs(logsDirUri) {
|
|
102
|
+
const logsDir = await this.fileService.resolve(logsDirUri);
|
|
103
|
+
const sessionDirs = (logsDir.children ?? [])
|
|
104
|
+
// we never clean a folder that is not a Theia logs session folder, even if it
|
|
105
|
+
// does appear under `logsDirUri`
|
|
106
|
+
.filter(child => child.isDirectory && SESSION_TIMESTAMP_PATTERN.test(child.resource.path.base))
|
|
107
|
+
.map(child => child.resource)
|
|
108
|
+
// newest first, so the oldest ones get cut off. Ordinal comparison, not
|
|
109
|
+
// localeCompare - the format is fixed ASCII, and locale-aware sorting could order
|
|
110
|
+
// it differently depending on the user's locale
|
|
111
|
+
.sort((one, other) => (0, strings_1.compare)(other.path.base, one.path.base));
|
|
112
|
+
const oldSessionDirs = sessionDirs.slice(const_1.PluginPaths.DEFAULT_PLUGIN_MAX_SESSION_LOGS_FOLDERS);
|
|
113
|
+
await Promise.all(oldSessionDirs.map(uri => this.fileService.delete(uri, { fromUserGesture: false, recursive: true })));
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Creates `uri` as a directory (fine if it already exists) and returns its path. Plugins get
|
|
117
|
+
* the path rather than the URI, e.g. as `ExtensionContext.storagePath`.
|
|
118
|
+
*/
|
|
119
|
+
async ensureDirectory(uri) {
|
|
120
|
+
await this.fileService.createFolder(uri, { fromUserGesture: false });
|
|
121
|
+
return this.fileService.fsPath(uri);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
exports.BrowserOnlyPluginPathsService = BrowserOnlyPluginPathsService;
|
|
125
|
+
tslib_1.__decorate([
|
|
126
|
+
(0, inversify_1.inject)(core_1.ILogger),
|
|
127
|
+
(0, inversify_1.named)('plugin-ext:BrowserOnlyPluginPathsService'),
|
|
128
|
+
tslib_1.__metadata("design:type", Object)
|
|
129
|
+
], BrowserOnlyPluginPathsService.prototype, "logger", void 0);
|
|
130
|
+
tslib_1.__decorate([
|
|
131
|
+
(0, inversify_1.inject)(env_variables_1.EnvVariablesServer),
|
|
132
|
+
tslib_1.__metadata("design:type", Object)
|
|
133
|
+
], BrowserOnlyPluginPathsService.prototype, "envServer", void 0);
|
|
134
|
+
tslib_1.__decorate([
|
|
135
|
+
(0, inversify_1.inject)(file_service_1.FileService),
|
|
136
|
+
tslib_1.__metadata("design:type", file_service_1.FileService)
|
|
137
|
+
], BrowserOnlyPluginPathsService.prototype, "fileService", void 0);
|
|
138
|
+
tslib_1.__decorate([
|
|
139
|
+
(0, inversify_1.inject)(common_1.UntitledWorkspaceService),
|
|
140
|
+
tslib_1.__metadata("design:type", common_1.UntitledWorkspaceService)
|
|
141
|
+
], BrowserOnlyPluginPathsService.prototype, "untitledWorkspaceService", void 0);
|
|
142
|
+
exports.BrowserOnlyPluginPathsService = BrowserOnlyPluginPathsService = tslib_1.__decorate([
|
|
143
|
+
(0, inversify_1.injectable)()
|
|
144
|
+
], BrowserOnlyPluginPathsService);
|
|
145
|
+
//# sourceMappingURL=browser-only-plugin-paths-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-only-plugin-paths-service.js","sourceRoot":"","sources":["../../../src/hosted/browser-only/browser-only-plugin-paths-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-only-plugin-paths-service.spec.d.ts","sourceRoot":"","sources":["../../../src/hosted/browser-only/browser-only-plugin-paths-service.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2026 Robert Jandow
|
|
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 jsdom_1 = require("@theia/core/lib/browser/test/jsdom");
|
|
19
|
+
// `FileService` transitively imports browser modules that touch `document` at load time.
|
|
20
|
+
const disableJSDOM = (0, jsdom_1.enableJSDOM)();
|
|
21
|
+
const chai_1 = require("chai");
|
|
22
|
+
const core_1 = require("@theia/core");
|
|
23
|
+
const uri_1 = require("@theia/core/lib/common/uri");
|
|
24
|
+
const mock_logger_1 = require("@theia/core/lib/common/test/mock-logger");
|
|
25
|
+
const inversify_1 = require("@theia/core/shared/inversify");
|
|
26
|
+
const env_variables_1 = require("@theia/core/lib/common/env-variables");
|
|
27
|
+
const file_service_1 = require("@theia/filesystem/lib/browser/file-service");
|
|
28
|
+
const common_1 = require("@theia/workspace/lib/common");
|
|
29
|
+
const browser_only_plugin_paths_service_1 = require("./browser-only-plugin-paths-service");
|
|
30
|
+
disableJSDOM();
|
|
31
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
32
|
+
/** The directories of the browser local file system, enough of it for the path service. */
|
|
33
|
+
class FakeFileService {
|
|
34
|
+
constructor() {
|
|
35
|
+
this.directories = new Set();
|
|
36
|
+
/** Lets tests assert that a cached path didn't go through {@link createFolder} again. */
|
|
37
|
+
this.createFolderCallCount = 0;
|
|
38
|
+
}
|
|
39
|
+
async createFolder(uri) {
|
|
40
|
+
this.createFolderCallCount++;
|
|
41
|
+
for (let current = uri; !current.path.isRoot; current = current.parent) {
|
|
42
|
+
this.directories.add(current.path.toString());
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async fsPath(uri) {
|
|
46
|
+
return uri.path.toString();
|
|
47
|
+
}
|
|
48
|
+
async resolve(uri) {
|
|
49
|
+
const parent = uri.path.toString();
|
|
50
|
+
const children = [...this.directories]
|
|
51
|
+
.filter(directory => new uri_1.default(directory).parent.path.toString() === parent)
|
|
52
|
+
.map(directory => ({ isDirectory: true, resource: new uri_1.default(directory) }));
|
|
53
|
+
return { isDirectory: true, resource: uri, children };
|
|
54
|
+
}
|
|
55
|
+
async delete(uri) {
|
|
56
|
+
const prefix = `${uri.path.toString()}/`;
|
|
57
|
+
for (const directory of [...this.directories]) {
|
|
58
|
+
if (directory === uri.path.toString() || directory.startsWith(prefix)) {
|
|
59
|
+
this.directories.delete(directory);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
describe('BrowserOnlyPluginPathsService', () => {
|
|
65
|
+
let fileService;
|
|
66
|
+
let service;
|
|
67
|
+
function createService() {
|
|
68
|
+
const container = new inversify_1.Container();
|
|
69
|
+
container.bind(browser_only_plugin_paths_service_1.BrowserOnlyPluginPathsService).toSelf().inSingletonScope();
|
|
70
|
+
container.bind(core_1.ILogger).to(mock_logger_1.MockLogger);
|
|
71
|
+
container.bind(file_service_1.FileService).toConstantValue(fileService);
|
|
72
|
+
container.bind(common_1.WorkspaceFileService).toSelf().inSingletonScope();
|
|
73
|
+
container.bind(common_1.UntitledWorkspaceService).toSelf().inSingletonScope();
|
|
74
|
+
container.bind(env_variables_1.EnvVariablesServer).toConstantValue({
|
|
75
|
+
getConfigDirUri: async () => 'file:///.theia'
|
|
76
|
+
});
|
|
77
|
+
return container.get(browser_only_plugin_paths_service_1.BrowserOnlyPluginPathsService);
|
|
78
|
+
}
|
|
79
|
+
/** A fake session folder name for the `session`th day of December 2025, e.g. `20251203T000000`. */
|
|
80
|
+
function sessionFolderName(session) {
|
|
81
|
+
const day = String(session).padStart(2, '0');
|
|
82
|
+
return `202512${day}T000000`;
|
|
83
|
+
}
|
|
84
|
+
function sessionFolderUri(session) {
|
|
85
|
+
return new uri_1.default(`file:///.theia/logs/${sessionFolderName(session)}/host`);
|
|
86
|
+
}
|
|
87
|
+
beforeEach(() => {
|
|
88
|
+
fileService = new FakeFileService();
|
|
89
|
+
service = createService();
|
|
90
|
+
});
|
|
91
|
+
describe('host log path', () => {
|
|
92
|
+
it('creates a session log folder', async () => {
|
|
93
|
+
const logPath = await service.getHostLogPath();
|
|
94
|
+
(0, chai_1.expect)(logPath).to.match(/^\/\.theia\/logs\/\d{8}T\d{6}\/host$/);
|
|
95
|
+
(0, chai_1.expect)(fileService.directories).to.include(logPath);
|
|
96
|
+
});
|
|
97
|
+
it('resolves the log path only once', async () => {
|
|
98
|
+
(0, chai_1.expect)(await service.getHostLogPath()).to.equal(await service.getHostLogPath());
|
|
99
|
+
});
|
|
100
|
+
it('keeps the ten most recent session folders, the one of this session among them', async () => {
|
|
101
|
+
for (let session = 1; session <= 12; session++) {
|
|
102
|
+
await fileService.createFolder(sessionFolderUri(session));
|
|
103
|
+
}
|
|
104
|
+
const logPath = await service.getHostLogPath();
|
|
105
|
+
const sessions = sessionFolders();
|
|
106
|
+
(0, chai_1.expect)(sessions).to.have.lengthOf(10);
|
|
107
|
+
(0, chai_1.expect)(logPath).to.contain(sessions.find(session => !session.startsWith('/.theia/logs/202512')));
|
|
108
|
+
// the three oldest gave way to the folder of this session
|
|
109
|
+
(0, chai_1.expect)(sessions).to.not.include(`/.theia/logs/${sessionFolderName(1)}`);
|
|
110
|
+
(0, chai_1.expect)(sessions).to.not.include(`/.theia/logs/${sessionFolderName(3)}`);
|
|
111
|
+
(0, chai_1.expect)(sessions).to.include(`/.theia/logs/${sessionFolderName(4)}`);
|
|
112
|
+
(0, chai_1.expect)(sessions).to.include(`/.theia/logs/${sessionFolderName(12)}`);
|
|
113
|
+
});
|
|
114
|
+
it('never cleans up a folder that is not a session folder', async () => {
|
|
115
|
+
for (let session = 1; session <= 12; session++) {
|
|
116
|
+
await fileService.createFolder(sessionFolderUri(session));
|
|
117
|
+
}
|
|
118
|
+
await fileService.createFolder(new uri_1.default('file:///.theia/logs/not-a-session'));
|
|
119
|
+
await service.getHostLogPath();
|
|
120
|
+
// getHostLogPath() doesn't wait for the cleanup, so give it a tick to finish
|
|
121
|
+
await new Promise(resolve => setImmediate(resolve));
|
|
122
|
+
(0, chai_1.expect)(fileService.directories).to.include('/.theia/logs/not-a-session');
|
|
123
|
+
});
|
|
124
|
+
function sessionFolders() {
|
|
125
|
+
return [...fileService.directories].filter(directory => /^\/\.theia\/logs\/[^/]+$/.test(directory)).sort();
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
describe('host storage path', () => {
|
|
129
|
+
it('has nowhere to store while no workspace is open', async () => {
|
|
130
|
+
(0, chai_1.expect)(await service.getHostStoragePath(undefined, [])).to.be.undefined;
|
|
131
|
+
});
|
|
132
|
+
it('gives every workspace a storage folder of its own', async () => {
|
|
133
|
+
const one = await service.getHostStoragePath('file:///one', []);
|
|
134
|
+
const other = await service.getHostStoragePath('file:///other', []);
|
|
135
|
+
(0, chai_1.expect)(one).to.match(/^\/\.theia\/workspace-storage\/.+$/);
|
|
136
|
+
(0, chai_1.expect)(one).to.not.equal(other);
|
|
137
|
+
(0, chai_1.expect)(fileService.directories).to.include(one);
|
|
138
|
+
});
|
|
139
|
+
it('gives a workspace the same storage folder in every session', async () => {
|
|
140
|
+
(0, chai_1.expect)(await service.getHostStoragePath('file:///one', [])).to.equal(await service.getHostStoragePath('file:///one', []));
|
|
141
|
+
});
|
|
142
|
+
it('keys the storage of an untitled workspace on its roots, which outlive its name', async () => {
|
|
143
|
+
const roots = ['file:///a', 'file:///b'];
|
|
144
|
+
const one = await service.getHostStoragePath('file:///.theia/workspaces/Untitled-1.theia-workspace', roots);
|
|
145
|
+
// the same roots under the name the next session gives the untitled workspace
|
|
146
|
+
const next = await service.getHostStoragePath('file:///.theia/workspaces/Untitled-2.theia-workspace', [...roots].reverse());
|
|
147
|
+
(0, chai_1.expect)(one).to.equal(next);
|
|
148
|
+
});
|
|
149
|
+
it('resolves the storage path only once per workspace', async () => {
|
|
150
|
+
await service.getHostStoragePath('file:///one', []);
|
|
151
|
+
const callsAfterFirst = fileService.createFolderCallCount;
|
|
152
|
+
await service.getHostStoragePath('file:///one', []);
|
|
153
|
+
(0, chai_1.expect)(fileService.createFolderCallCount).to.equal(callsAfterFirst);
|
|
154
|
+
});
|
|
155
|
+
it('resolves a new storage path when the roots of an untitled workspace change', async () => {
|
|
156
|
+
const workspaceUri = 'file:///.theia/workspaces/Untitled-1.theia-workspace';
|
|
157
|
+
const first = await service.getHostStoragePath(workspaceUri, ['file:///a']);
|
|
158
|
+
const callsAfterFirst = fileService.createFolderCallCount;
|
|
159
|
+
const second = await service.getHostStoragePath(workspaceUri, ['file:///a', 'file:///b']);
|
|
160
|
+
(0, chai_1.expect)(second).to.not.equal(first);
|
|
161
|
+
(0, chai_1.expect)(fileService.createFolderCallCount).to.be.greaterThan(callsAfterFirst);
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
//# sourceMappingURL=browser-only-plugin-paths-service.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-only-plugin-paths-service.spec.js","sourceRoot":"","sources":["../../../src/hosted/browser-only/browser-only-plugin-paths-service.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Mutex } from 'async-mutex';
|
|
2
|
+
import { ILogger } from '@theia/core';
|
|
3
|
+
import { StorageService } from '@theia/core/lib/browser/storage-service';
|
|
4
|
+
import { PluginDeployOptions, PluginIdentifiers, PluginServer, PluginStorageKind, PluginType } from '../../common';
|
|
5
|
+
import { KeysToAnyValues, KeysToKeysToAnyValue } from '../../common/types';
|
|
6
|
+
import { PluginPathsService } from '../../main/common/plugin-paths-protocol';
|
|
7
|
+
/**
|
|
8
|
+
* Plugins of a browser-only application are deployed at build time, so they can't be installed,
|
|
9
|
+
* uninstalled, enabled or disabled at runtime. The queries just report an empty result instead
|
|
10
|
+
* of failing, so callers like the plugin view still have something to render.
|
|
11
|
+
*
|
|
12
|
+
* The plugin key-value storage backing `ExtensionContext.globalState` and
|
|
13
|
+
* `ExtensionContext.workspaceState` lives in the browser's local storage.
|
|
14
|
+
*/
|
|
15
|
+
export declare class BrowserOnlyPluginServer implements PluginServer {
|
|
16
|
+
protected readonly logger: ILogger;
|
|
17
|
+
protected readonly storageService: StorageService;
|
|
18
|
+
protected readonly pluginPathsService: PluginPathsService;
|
|
19
|
+
/** Fallback for {@link withStoreLock} when the Web Locks API is unavailable. */
|
|
20
|
+
protected readonly localLock: Mutex;
|
|
21
|
+
protected missingLocksWarned: boolean;
|
|
22
|
+
install(pluginEntry: string, type?: PluginType, options?: PluginDeployOptions): Promise<void>;
|
|
23
|
+
uninstall(pluginId: PluginIdentifiers.VersionedId): Promise<void>;
|
|
24
|
+
enablePlugin(pluginId: PluginIdentifiers.UnversionedId): Promise<boolean>;
|
|
25
|
+
disablePlugin(pluginId: PluginIdentifiers.UnversionedId): Promise<boolean>;
|
|
26
|
+
getInstalledPlugins(): Promise<readonly PluginIdentifiers.VersionedId[]>;
|
|
27
|
+
getUninstalledPlugins(): Promise<readonly PluginIdentifiers.VersionedId[]>;
|
|
28
|
+
getDisabledPlugins(): Promise<readonly PluginIdentifiers.UnversionedId[]>;
|
|
29
|
+
setStorageValue(key: string, value: KeysToAnyValues, kind: PluginStorageKind): Promise<boolean>;
|
|
30
|
+
getStorageValue(key: string, kind: PluginStorageKind): Promise<KeysToAnyValues>;
|
|
31
|
+
getAllStorageValues(kind: PluginStorageKind): Promise<KeysToKeysToAnyValue>;
|
|
32
|
+
protected getStore(storeKey: string): Promise<KeysToKeysToAnyValue>;
|
|
33
|
+
/**
|
|
34
|
+
* Runs `task` while holding the cross-tab lock for `storeKey`, via the Web Locks API, so a
|
|
35
|
+
* concurrent {@link setStorageValue} on this or another tab can't interleave with it.
|
|
36
|
+
*/
|
|
37
|
+
protected withStoreLock<T>(storeKey: string, task: () => Promise<T>): Promise<T>;
|
|
38
|
+
/** The Web Locks API of this browsing context, or `undefined` in an insecure context or an older browser. */
|
|
39
|
+
protected getWebLocks(): LockManager | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* Requests `name` from `locks` and runs `callback` once granted, same as `LockManager.request()`.
|
|
42
|
+
*
|
|
43
|
+
* `LockGrantedCallback` is typed as `(lock: Lock | null) => T`, which doesn't account for an
|
|
44
|
+
* async or never-settling callback even though the API itself supports and awaits one, hence
|
|
45
|
+
* the cast. Kept as its own method so a subclass or test can swap the lock implementation.
|
|
46
|
+
*/
|
|
47
|
+
protected requestLock<T>(locks: LockManager, name: string, callback: () => T | PromiseLike<T>): Promise<T>;
|
|
48
|
+
/**
|
|
49
|
+
* The browser storage key holding the given kind of values, or `undefined` if there's
|
|
50
|
+
* nowhere to keep them - e.g. workspace state while no workspace is open.
|
|
51
|
+
*/
|
|
52
|
+
protected getStoreKey(kind: PluginStorageKind): Promise<string | undefined>;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=browser-only-plugin-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-only-plugin-server.d.ts","sourceRoot":"","sources":["../../../src/hosted/browser-only/browser-only-plugin-server.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,OAAO,EAAO,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAuB,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAC9F,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACnH,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAM7E;;;;;;;GAOG;AACH,qBACa,uBAAwB,YAAW,YAAY;IAGxD,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAOnC,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IAGlD,SAAS,CAAC,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;IAE1D,gFAAgF;IAChF,SAAS,CAAC,QAAQ,CAAC,SAAS,QAAe;IAC3C,SAAS,CAAC,kBAAkB,UAAS;IAE/B,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7F,SAAS,CAAC,QAAQ,EAAE,iBAAiB,CAAC,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjE,YAAY,CAAC,QAAQ,EAAE,iBAAiB,CAAC,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC;IAIzE,aAAa,CAAC,QAAQ,EAAE,iBAAiB,CAAC,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC;IAI1E,mBAAmB,IAAI,OAAO,CAAC,SAAS,iBAAiB,CAAC,WAAW,EAAE,CAAC;IAIxE,qBAAqB,IAAI,OAAO,CAAC,SAAS,iBAAiB,CAAC,WAAW,EAAE,CAAC;IAI1E,kBAAkB,IAAI,OAAO,CAAC,SAAS,iBAAiB,CAAC,aAAa,EAAE,CAAC;IAIzE,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAqB/F,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,eAAe,CAAC;IAI/E,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAKjF,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAInE;;;OAGG;IACH,SAAS,CAAC,aAAa,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAchF,6GAA6G;IAC7G,SAAS,CAAC,WAAW,IAAI,WAAW,GAAG,SAAS;IAIhD;;;;;;OAMG;IACH,SAAS,CAAC,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAI1G;;;OAGG;cACa,WAAW,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;CAQpF"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2026 Robert Jandow
|
|
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
|
+
exports.BrowserOnlyPluginServer = void 0;
|
|
19
|
+
const tslib_1 = require("tslib");
|
|
20
|
+
const inversify_1 = require("@theia/core/shared/inversify");
|
|
21
|
+
const async_mutex_1 = require("async-mutex");
|
|
22
|
+
const core_1 = require("@theia/core");
|
|
23
|
+
const storage_service_1 = require("@theia/core/lib/browser/storage-service");
|
|
24
|
+
const plugin_paths_protocol_1 = require("../../main/common/plugin-paths-protocol");
|
|
25
|
+
const GLOBAL_STORAGE_KEY = 'plugin-storage:global';
|
|
26
|
+
const WORKSPACE_STORAGE_KEY_PREFIX = 'plugin-storage:workspace:';
|
|
27
|
+
const LOCK_NAME_PREFIX = 'theia:plugin-storage:';
|
|
28
|
+
/**
|
|
29
|
+
* Plugins of a browser-only application are deployed at build time, so they can't be installed,
|
|
30
|
+
* uninstalled, enabled or disabled at runtime. The queries just report an empty result instead
|
|
31
|
+
* of failing, so callers like the plugin view still have something to render.
|
|
32
|
+
*
|
|
33
|
+
* The plugin key-value storage backing `ExtensionContext.globalState` and
|
|
34
|
+
* `ExtensionContext.workspaceState` lives in the browser's local storage.
|
|
35
|
+
*/
|
|
36
|
+
let BrowserOnlyPluginServer = class BrowserOnlyPluginServer {
|
|
37
|
+
constructor() {
|
|
38
|
+
/** Fallback for {@link withStoreLock} when the Web Locks API is unavailable. */
|
|
39
|
+
this.localLock = new async_mutex_1.Mutex();
|
|
40
|
+
this.missingLocksWarned = false;
|
|
41
|
+
}
|
|
42
|
+
async install(pluginEntry, type, options) {
|
|
43
|
+
throw new Error(core_1.nls.localize('theia/plugin-ext/browserOnlyInstallUnsupported', 'Installing plugins is not supported in a browser-only application.'));
|
|
44
|
+
}
|
|
45
|
+
async uninstall(pluginId) {
|
|
46
|
+
throw new Error(core_1.nls.localize('theia/plugin-ext/browserOnlyUninstallUnsupported', 'Uninstalling plugins is not supported in a browser-only application.'));
|
|
47
|
+
}
|
|
48
|
+
async enablePlugin(pluginId) {
|
|
49
|
+
throw new Error(core_1.nls.localize('theia/plugin-ext/browserOnlyEnableUnsupported', 'Enabling plugins is not supported in a browser-only application.'));
|
|
50
|
+
}
|
|
51
|
+
async disablePlugin(pluginId) {
|
|
52
|
+
throw new Error(core_1.nls.localize('theia/plugin-ext/browserOnlyDisableUnsupported', 'Disabling plugins is not supported in a browser-only application.'));
|
|
53
|
+
}
|
|
54
|
+
async getInstalledPlugins() {
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
async getUninstalledPlugins() {
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
async getDisabledPlugins() {
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
async setStorageValue(key, value, kind) {
|
|
64
|
+
const storeKey = await this.getStoreKey(kind);
|
|
65
|
+
if (!storeKey) {
|
|
66
|
+
this.logger.warn('Cannot save plugin data: no opened workspace.');
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
// the browser storage is shared with this application's other tabs, each running its own
|
|
70
|
+
// plugin host, so the read and write below need to be atomic - otherwise a concurrent
|
|
71
|
+
// update from another tab could land in between and get overwritten by this one
|
|
72
|
+
await this.withStoreLock(storeKey, async () => {
|
|
73
|
+
const store = await this.getStore(storeKey);
|
|
74
|
+
if (value === undefined || Object.keys(value).length === 0) {
|
|
75
|
+
delete store[key];
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
store[key] = value;
|
|
79
|
+
}
|
|
80
|
+
await this.storageService.setData(storeKey, store);
|
|
81
|
+
});
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
async getStorageValue(key, kind) {
|
|
85
|
+
return (await this.getAllStorageValues(kind))[key] ?? {};
|
|
86
|
+
}
|
|
87
|
+
async getAllStorageValues(kind) {
|
|
88
|
+
const storeKey = await this.getStoreKey(kind);
|
|
89
|
+
return storeKey ? this.getStore(storeKey) : {};
|
|
90
|
+
}
|
|
91
|
+
getStore(storeKey) {
|
|
92
|
+
return this.storageService.getData(storeKey, {});
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Runs `task` while holding the cross-tab lock for `storeKey`, via the Web Locks API, so a
|
|
96
|
+
* concurrent {@link setStorageValue} on this or another tab can't interleave with it.
|
|
97
|
+
*/
|
|
98
|
+
withStoreLock(storeKey, task) {
|
|
99
|
+
const locks = this.getWebLocks();
|
|
100
|
+
if (locks) {
|
|
101
|
+
return this.requestLock(locks, `${LOCK_NAME_PREFIX}${storeKey}`, task);
|
|
102
|
+
}
|
|
103
|
+
// no Web Locks API (insecure context, older browser): fall back to serializing writes
|
|
104
|
+
// within this tab. A write from another tab can still race and get lost.
|
|
105
|
+
if (!this.missingLocksWarned) {
|
|
106
|
+
this.missingLocksWarned = true;
|
|
107
|
+
this.logger.warn('Web Locks API unavailable: plugin storage updates from different tabs may race.');
|
|
108
|
+
}
|
|
109
|
+
return this.localLock.runExclusive(task);
|
|
110
|
+
}
|
|
111
|
+
/** The Web Locks API of this browsing context, or `undefined` in an insecure context or an older browser. */
|
|
112
|
+
getWebLocks() {
|
|
113
|
+
return typeof navigator === 'object' ? navigator.locks : undefined;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Requests `name` from `locks` and runs `callback` once granted, same as `LockManager.request()`.
|
|
117
|
+
*
|
|
118
|
+
* `LockGrantedCallback` is typed as `(lock: Lock | null) => T`, which doesn't account for an
|
|
119
|
+
* async or never-settling callback even though the API itself supports and awaits one, hence
|
|
120
|
+
* the cast. Kept as its own method so a subclass or test can swap the lock implementation.
|
|
121
|
+
*/
|
|
122
|
+
requestLock(locks, name, callback) {
|
|
123
|
+
return locks.request(name, callback);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* The browser storage key holding the given kind of values, or `undefined` if there's
|
|
127
|
+
* nowhere to keep them - e.g. workspace state while no workspace is open.
|
|
128
|
+
*/
|
|
129
|
+
async getStoreKey(kind) {
|
|
130
|
+
if (!kind) {
|
|
131
|
+
return GLOBAL_STORAGE_KEY;
|
|
132
|
+
}
|
|
133
|
+
// derived from the storage path so workspace state follows `ExtensionContext.storageUri`
|
|
134
|
+
const storagePath = await this.pluginPathsService.getHostStoragePath(kind.workspace, kind.roots);
|
|
135
|
+
return storagePath && `${WORKSPACE_STORAGE_KEY_PREFIX}${storagePath}`;
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
exports.BrowserOnlyPluginServer = BrowserOnlyPluginServer;
|
|
139
|
+
tslib_1.__decorate([
|
|
140
|
+
(0, inversify_1.inject)(core_1.ILogger),
|
|
141
|
+
(0, inversify_1.named)('plugin-ext:BrowserOnlyPluginServer'),
|
|
142
|
+
tslib_1.__metadata("design:type", Object)
|
|
143
|
+
], BrowserOnlyPluginServer.prototype, "logger", void 0);
|
|
144
|
+
tslib_1.__decorate([
|
|
145
|
+
(0, inversify_1.inject)(storage_service_1.LocalStorageService),
|
|
146
|
+
tslib_1.__metadata("design:type", Object)
|
|
147
|
+
], BrowserOnlyPluginServer.prototype, "storageService", void 0);
|
|
148
|
+
tslib_1.__decorate([
|
|
149
|
+
(0, inversify_1.inject)(plugin_paths_protocol_1.PluginPathsService),
|
|
150
|
+
tslib_1.__metadata("design:type", Object)
|
|
151
|
+
], BrowserOnlyPluginServer.prototype, "pluginPathsService", void 0);
|
|
152
|
+
exports.BrowserOnlyPluginServer = BrowserOnlyPluginServer = tslib_1.__decorate([
|
|
153
|
+
(0, inversify_1.injectable)()
|
|
154
|
+
], BrowserOnlyPluginServer);
|
|
155
|
+
//# sourceMappingURL=browser-only-plugin-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-only-plugin-server.js","sourceRoot":"","sources":["../../../src/hosted/browser-only/browser-only-plugin-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-only-plugin-server.spec.d.ts","sourceRoot":"","sources":["../../../src/hosted/browser-only/browser-only-plugin-server.spec.ts"],"names":[],"mappings":""}
|