@theia/plugin-ext 1.76.0-next.4 → 1.76.0-next.42

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 (93) hide show
  1. package/lib/common/plugin-api-rpc.d.ts +14 -0
  2. package/lib/common/plugin-api-rpc.d.ts.map +1 -1
  3. package/lib/common/plugin-api-rpc.js +1 -1
  4. package/lib/common/plugin-api-rpc.js.map +1 -1
  5. package/lib/hosted/browser/hosted-plugin.d.ts +2 -0
  6. package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
  7. package/lib/hosted/browser/hosted-plugin.js +8 -2
  8. package/lib/hosted/browser/hosted-plugin.js.map +1 -1
  9. package/lib/hosted/browser/worker/worker-main.js +3 -1
  10. package/lib/hosted/browser/worker/worker-main.js.map +1 -1
  11. package/lib/hosted/browser/worker/worker-plugin-module.d.ts.map +1 -1
  12. package/lib/hosted/browser/worker/worker-plugin-module.js +2 -0
  13. package/lib/hosted/browser/worker/worker-plugin-module.js.map +1 -1
  14. package/lib/hosted/node/plugin-host-module.d.ts.map +1 -1
  15. package/lib/hosted/node/plugin-host-module.js +2 -0
  16. package/lib/hosted/node/plugin-host-module.js.map +1 -1
  17. package/lib/hosted/node/plugin-host-rpc.d.ts +3 -0
  18. package/lib/hosted/node/plugin-host-rpc.d.ts.map +1 -1
  19. package/lib/hosted/node/plugin-host-rpc.js +9 -3
  20. package/lib/hosted/node/plugin-host-rpc.js.map +1 -1
  21. package/lib/main/browser/editors-and-documents-main.d.ts +7 -0
  22. package/lib/main/browser/editors-and-documents-main.d.ts.map +1 -1
  23. package/lib/main/browser/editors-and-documents-main.js +19 -9
  24. package/lib/main/browser/editors-and-documents-main.js.map +1 -1
  25. package/lib/main/browser/editors-and-documents-main.spec.d.ts +2 -0
  26. package/lib/main/browser/editors-and-documents-main.spec.d.ts.map +1 -0
  27. package/lib/main/browser/editors-and-documents-main.spec.js +117 -0
  28. package/lib/main/browser/editors-and-documents-main.spec.js.map +1 -0
  29. package/lib/main/browser/languages-main.d.ts +7 -0
  30. package/lib/main/browser/languages-main.d.ts.map +1 -1
  31. package/lib/main/browser/languages-main.js +31 -9
  32. package/lib/main/browser/languages-main.js.map +1 -1
  33. package/lib/main/browser/languages-main.spec.d.ts +2 -0
  34. package/lib/main/browser/languages-main.spec.d.ts.map +1 -0
  35. package/lib/main/browser/languages-main.spec.js +82 -0
  36. package/lib/main/browser/languages-main.spec.js.map +1 -0
  37. package/lib/main/browser/main-context.d.ts.map +1 -1
  38. package/lib/main/browser/main-context.js +3 -0
  39. package/lib/main/browser/main-context.js.map +1 -1
  40. package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts +5 -0
  41. package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts.map +1 -1
  42. package/lib/main/browser/menus/vscode-theia-menu-mappings.js +5 -0
  43. package/lib/main/browser/menus/vscode-theia-menu-mappings.js.map +1 -1
  44. package/lib/main/browser/plugin-ext-frontend-module.d.ts.map +1 -1
  45. package/lib/main/browser/plugin-ext-frontend-module.js +1 -0
  46. package/lib/main/browser/plugin-ext-frontend-module.js.map +1 -1
  47. package/lib/main/browser/telemetry-main.d.ts +20 -0
  48. package/lib/main/browser/telemetry-main.d.ts.map +1 -0
  49. package/lib/main/browser/telemetry-main.js +43 -0
  50. package/lib/main/browser/telemetry-main.js.map +1 -0
  51. package/lib/main/browser/telemetry-main.spec.d.ts +2 -0
  52. package/lib/main/browser/telemetry-main.spec.d.ts.map +1 -0
  53. package/lib/main/browser/telemetry-main.spec.js +66 -0
  54. package/lib/main/browser/telemetry-main.spec.js.map +1 -0
  55. package/lib/main/browser/webview/webview-context-keys.d.ts +3 -2
  56. package/lib/main/browser/webview/webview-context-keys.d.ts.map +1 -1
  57. package/lib/main/browser/webview/webview-context-keys.js +16 -2
  58. package/lib/main/browser/webview/webview-context-keys.js.map +1 -1
  59. package/lib/plugin/plugin-context.d.ts +2 -1
  60. package/lib/plugin/plugin-context.d.ts.map +1 -1
  61. package/lib/plugin/plugin-context.js +2 -3
  62. package/lib/plugin/plugin-context.js.map +1 -1
  63. package/lib/plugin/plugin-manager.d.ts +2 -0
  64. package/lib/plugin/plugin-manager.d.ts.map +1 -1
  65. package/lib/plugin/plugin-manager.js +7 -0
  66. package/lib/plugin/plugin-manager.js.map +1 -1
  67. package/lib/plugin/telemetry-ext.d.ts +23 -7
  68. package/lib/plugin/telemetry-ext.d.ts.map +1 -1
  69. package/lib/plugin/telemetry-ext.js +60 -33
  70. package/lib/plugin/telemetry-ext.js.map +1 -1
  71. package/lib/plugin/telemetry-ext.spec.js +121 -16
  72. package/lib/plugin/telemetry-ext.spec.js.map +1 -1
  73. package/package.json +32 -31
  74. package/src/common/plugin-api-rpc.ts +15 -1
  75. package/src/hosted/browser/hosted-plugin.ts +7 -2
  76. package/src/hosted/browser/worker/worker-main.ts +4 -1
  77. package/src/hosted/browser/worker/worker-plugin-module.ts +2 -0
  78. package/src/hosted/node/plugin-host-module.ts +2 -0
  79. package/src/hosted/node/plugin-host-rpc.ts +10 -4
  80. package/src/main/browser/editors-and-documents-main.spec.ts +140 -0
  81. package/src/main/browser/editors-and-documents-main.ts +19 -7
  82. package/src/main/browser/languages-main.spec.ts +101 -0
  83. package/src/main/browser/languages-main.ts +31 -9
  84. package/src/main/browser/main-context.ts +4 -0
  85. package/src/main/browser/menus/vscode-theia-menu-mappings.ts +5 -0
  86. package/src/main/browser/plugin-ext-frontend-module.ts +2 -1
  87. package/src/main/browser/telemetry-main.spec.ts +77 -0
  88. package/src/main/browser/telemetry-main.ts +46 -0
  89. package/src/main/browser/webview/webview-context-keys.ts +20 -4
  90. package/src/plugin/plugin-context.ts +3 -2
  91. package/src/plugin/plugin-manager.ts +6 -0
  92. package/src/plugin/telemetry-ext.spec.ts +158 -17
  93. package/src/plugin/telemetry-ext.ts +63 -33
@@ -14,33 +14,54 @@
14
14
  // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
15
 
16
16
  import { Event, Emitter } from '@theia/core/lib/common/event';
17
+ import { Disposable } from '@theia/core/lib/common/disposable';
17
18
  import { cloneAndChange } from '@theia/core';
19
+ import { injectable } from '@theia/core/shared/inversify';
20
+ import { TelemetryLevel, isKindAllowedByLevel } from '@theia/telemetry/lib/common/telemetry-types';
21
+ import { TelemetryExt } from '../common/plugin-api-rpc';
18
22
  import { mixin } from '../common/types';
19
23
  import { TelemetryTrustedValue, TelemetryLoggerOptions } from './types-impl';
20
24
 
21
- export class TelemetryExtImpl {
25
+ /**
26
+ * Holds the telemetry level the user consented to and hands it to the loggers plugins create.
27
+ *
28
+ * @experimental
29
+ */
30
+ @injectable()
31
+ export class TelemetryExtImpl implements TelemetryExt {
22
32
 
23
- _isTelemetryEnabled: boolean = false; // telemetry not activated by default
33
+ protected currentLevel: TelemetryLevel = 'off';
24
34
  private readonly onDidChangeTelemetryEnabledEmitter = new Emitter<boolean>();
25
35
  readonly onDidChangeTelemetryEnabled: Event<boolean> = this.onDidChangeTelemetryEnabledEmitter.event;
36
+ private readonly onDidChangeTelemetryLevelEmitter = new Emitter<TelemetryLevel>();
37
+ protected readonly onDidChangeTelemetryLevel: Event<TelemetryLevel> = this.onDidChangeTelemetryLevelEmitter.event;
26
38
 
27
- get isTelemetryEnabled(): boolean {
28
- return this._isTelemetryEnabled;
39
+ get level(): TelemetryLevel {
40
+ return this.currentLevel;
29
41
  }
30
42
 
31
- set isTelemetryEnabled(isTelemetryEnabled: boolean) {
32
- if (this._isTelemetryEnabled !== isTelemetryEnabled) {
33
- this._isTelemetryEnabled = isTelemetryEnabled;
34
- this.onDidChangeTelemetryEnabledEmitter.fire(this._isTelemetryEnabled);
43
+ $onDidChangeTelemetryLevel(level: TelemetryLevel): void {
44
+ this.setLevel(level);
45
+ }
46
+
47
+ setLevel(level: TelemetryLevel): void {
48
+ if (this.currentLevel === level) {
49
+ return;
35
50
  }
51
+ const wasTelemetryEnabled = this.isTelemetryEnabled;
52
+ this.currentLevel = level;
53
+ this.onDidChangeTelemetryLevelEmitter.fire(level);
54
+ if (this.isTelemetryEnabled !== wasTelemetryEnabled) {
55
+ this.onDidChangeTelemetryEnabledEmitter.fire(this.isTelemetryEnabled);
56
+ }
57
+ }
58
+
59
+ get isTelemetryEnabled(): boolean {
60
+ return isKindAllowedByLevel(this.currentLevel, 'usage');
36
61
  }
37
62
 
38
63
  createTelemetryLogger(sender: TelemetrySender, options?: TelemetryLoggerOptions | undefined): TelemetryLogger {
39
- const logger = new TelemetryLogger(sender, this._isTelemetryEnabled, options);
40
- this.onDidChangeTelemetryEnabled(isEnabled => {
41
- logger.telemetryEnabled = isEnabled;
42
- });
43
- return logger;
64
+ return new TelemetryLogger(sender, this.currentLevel, this.onDidChangeTelemetryLevel, options);
44
65
  }
45
66
  }
46
67
 
@@ -49,30 +70,36 @@ export class TelemetryLogger {
49
70
  readonly options: TelemetryLoggerOptions | undefined;
50
71
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
51
72
  readonly commonProperties: Record<string, any>;
52
- private _telemetryEnabled: boolean;
73
+ private _level: TelemetryLevel;
53
74
 
54
75
  private readonly onDidChangeEnableStatesEmitter: Emitter<TelemetryLogger> = new Emitter();
55
76
  readonly onDidChangeEnableStates: Event<TelemetryLogger> = this.onDidChangeEnableStatesEmitter.event;
56
77
  private _isUsageEnabled: boolean;
57
78
  private _isErrorsEnabled: boolean;
79
+ private readonly levelSubscription: Disposable;
58
80
 
59
- constructor(sender: TelemetrySender, telemetryEnabled: boolean, options?: TelemetryLoggerOptions) {
81
+ constructor(sender: TelemetrySender, level: TelemetryLevel, onDidChangeTelemetryLevel: Event<TelemetryLevel>, options?: TelemetryLoggerOptions) {
60
82
  this.sender = sender;
61
83
  this.options = options;
62
84
  this.commonProperties = this.getCommonProperties();
63
- this._telemetryEnabled = telemetryEnabled;
64
- this._isErrorsEnabled = telemetryEnabled;
65
- this._isUsageEnabled = telemetryEnabled;
85
+ this._level = level;
86
+ this._isErrorsEnabled = isKindAllowedByLevel(level, 'error');
87
+ this._isUsageEnabled = isKindAllowedByLevel(level, 'usage');
88
+ this.levelSubscription = onDidChangeTelemetryLevel(next => this.applyLevel(next));
66
89
  }
67
90
 
68
- get telemetryEnabled(): boolean {
69
- return this._telemetryEnabled;
91
+ /**
92
+ * The telemetry level the user consented to. Must stay read-only: the object handed to a plugin is proxied with a
93
+ * `get` trap only, so a setter here would let the plugin raise its own gate.
94
+ */
95
+ get level(): TelemetryLevel {
96
+ return this._level;
70
97
  }
71
98
 
72
- set telemetryEnabled(telemetryEnabled: boolean) {
73
- if (this._telemetryEnabled !== telemetryEnabled) {
74
- this._telemetryEnabled = telemetryEnabled;
75
- this.updateEnableStates(telemetryEnabled, telemetryEnabled);
99
+ private applyLevel(level: TelemetryLevel): void {
100
+ if (this._level !== level) {
101
+ this._level = level;
102
+ this.updateEnableStates(isKindAllowedByLevel(level, 'usage'), isKindAllowedByLevel(level, 'error'));
76
103
  }
77
104
  }
78
105
 
@@ -108,7 +135,7 @@ export class TelemetryLogger {
108
135
 
109
136
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
110
137
  logUsage(eventName: string, data?: Record<string, any | TelemetryTrustedValue<any>>): void {
111
- if (!this.telemetryEnabled || !this.isUsageEnabled) {
138
+ if (!isKindAllowedByLevel(this._level, 'usage') || !this.isUsageEnabled) {
112
139
  return;
113
140
  }
114
141
  this.logEvent(eventName, data);
@@ -116,7 +143,7 @@ export class TelemetryLogger {
116
143
 
117
144
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
118
145
  logError(eventNameOrException: string | Error, data?: Record<string, any | TelemetryTrustedValue<any>>): void {
119
- if (!this.telemetryEnabled || !this.isErrorsEnabled || !this.sender) {
146
+ if (!isKindAllowedByLevel(this._level, 'error') || !this.isErrorsEnabled || !this.sender) {
120
147
  // no sender available or error shall not be sent
121
148
  return;
122
149
  }
@@ -128,14 +155,17 @@ export class TelemetryLogger {
128
155
  }
129
156
 
130
157
  dispose(): void {
131
- if (this.sender?.flush) {
132
- let tempSender: TelemetrySender | undefined = this.sender;
133
- this.sender = undefined;
134
- Promise.resolve(tempSender.flush!()).then(tempSender = undefined);
135
- } else {
136
- this.sender = undefined;
158
+ this.levelSubscription.dispose();
159
+ this.onDidChangeEnableStatesEmitter.dispose();
160
+ const sender = this.sender;
161
+ this.sender = undefined;
162
+ const reportFlushFailure = (error: unknown): void => console.error('Failed to flush the telemetry sender.', error);
163
+ try {
164
+ Promise.resolve(sender?.flush?.()).catch(reportFlushFailure);
165
+ } catch (error) {
166
+ reportFlushFailure(error);
137
167
  }
138
- };
168
+ }
139
169
 
140
170
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
141
171
  private logEvent(eventName: string, data?: Record<string, any>): void {