@pooder/core 2.0.0 → 2.2.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/src/extension.ts CHANGED
@@ -1,164 +1,177 @@
1
- import { ExtensionContext } from "./context";
2
- import { Contribution, ContributionPointIds } from "./contribution";
3
- import Disposable from "./disposable";
4
- import CommandService from "./services/CommandService";
5
- import { ConfigurationService } from "./services";
6
-
7
- interface ExtensionMetadata {
8
- name: string;
9
- }
10
-
11
- interface Extension {
12
- id: string;
13
- metadata?: Partial<ExtensionMetadata>;
14
-
15
- activate(context: ExtensionContext): void;
16
- deactivate(context: ExtensionContext): void;
17
- contribute?(): Record<string, any[]>;
18
- }
19
-
20
- class ExtensionRegistry extends Map<string, Extension> {}
21
-
22
- class ExtensionManager {
23
- private readonly context: ExtensionContext;
24
- private extensionRegistry: ExtensionRegistry = new ExtensionRegistry();
25
- private extensionDisposables: Map<string, Disposable[]> = new Map();
26
-
27
- constructor(context: ExtensionContext) {
28
- this.context = context;
29
- }
30
-
31
- register(extension: Extension) {
32
- if (this.extensionRegistry.has(extension.id)) {
33
- console.warn(
34
- `Plugin "${extension.id}" already registered. It will be overwritten.`,
35
- );
36
- }
37
-
38
- // Initialize disposables for this extension
39
- this.extensionDisposables.set(extension.id, []);
40
- const disposables = this.extensionDisposables.get(extension.id)!;
41
-
42
- // Process declarative contributions
43
- if (extension.contribute) {
44
- for (const [pointId, items] of Object.entries(extension.contribute())) {
45
- if (Array.isArray(items)) {
46
- items.forEach((item, index) => {
47
- const contributionId =
48
- item.id ||
49
- (item.command
50
- ? item.command
51
- : `${extension.id}.${pointId}.${index}`);
52
- const contribution: Contribution = {
53
- id: contributionId,
54
- metadata: {
55
- extensionId: extension.id,
56
- ...item?.metadata,
57
- },
58
- data: item,
59
- };
60
- const disposable = this.context.contributions.register(
61
- pointId,
62
- contribution,
63
- );
64
-
65
- // Track contribution registration to unregister later
66
- disposables.push(disposable);
67
-
68
- const dispose = this.collectContribution(pointId, contribution);
69
- if (dispose) {
70
- disposables.push(dispose);
71
- }
72
- });
73
- }
74
- }
75
- }
76
-
77
- try {
78
- this.extensionRegistry.set(extension.id, extension);
79
- this.context.eventBus.emit("extension:register", extension);
80
- } catch (error) {
81
- console.error(
82
- `Error in onCreate hook for plugin "${extension.id}":`,
83
- error,
84
- );
85
- }
86
-
87
- try {
88
- extension.activate(this.context);
89
- } catch (error) {
90
- console.error(
91
- `Error in onActivate hook for plugin "${extension.id}":`,
92
- error,
93
- );
94
- }
95
-
96
- console.log(`Plugin "${extension.id}" registered successfully`);
97
- }
98
-
99
- collectContribution(pointId: string, item: any): Disposable | undefined {
100
- // If registering configurations, update ConfigurationService defaults
101
- if (pointId === ContributionPointIds.CONFIGURATIONS) {
102
- const configService = this.context.services.get<ConfigurationService>(
103
- "ConfigurationService",
104
- );
105
- configService?.initializeDefaults([item.data]);
106
- }
107
- if (pointId === ContributionPointIds.COMMANDS && item.data.handler) {
108
- const commandService =
109
- this.context.services.get<CommandService>("CommandService")!;
110
-
111
- return commandService.registerCommand(item.id, item.data.handler);
112
- }
113
- }
114
-
115
- unregister(name: string) {
116
- const extension = this.extensionRegistry.get(name);
117
- if (!extension) {
118
- console.warn(`Plugin "${name}" not found.`);
119
- return;
120
- }
121
-
122
- try {
123
- extension.deactivate(this.context);
124
- } catch (error) {
125
- console.error(`Error in deactivate for plugin "${name}":`, error);
126
- }
127
-
128
- // Dispose all resources associated with this extension
129
- const disposables = this.extensionDisposables.get(name);
130
- if (disposables) {
131
- disposables.forEach((d) => d.dispose());
132
- this.extensionDisposables.delete(name);
133
- }
134
-
135
- this.extensionRegistry.delete(name);
136
- console.log(`Plugin "${name}" unregistered`);
137
- return true;
138
- }
139
-
140
- enable(name: string) {
141
- const extension = this.extensionRegistry.get(name);
142
- if (!extension) {
143
- console.warn(`Plugin "${name}" not found.`);
144
- return;
145
- }
146
- }
147
-
148
- disable(name: string) {
149
- const extension = this.extensionRegistry.get(name);
150
- if (!extension) {
151
- console.warn(`Plugin "${name}" not found.`);
152
- return;
153
- }
154
- }
155
-
156
- update() {}
157
-
158
- destroy() {
159
- const extensionNames = Array.from(this.extensionRegistry.keys());
160
- extensionNames.forEach((name) => this.unregister(name));
161
- }
162
- }
163
-
164
- export { Extension, ExtensionMetadata, ExtensionRegistry, ExtensionManager };
1
+ import { ExtensionContext } from "./context";
2
+ import { Contribution, ContributionPointIds } from "./contribution";
3
+ import Disposable from "./disposable";
4
+ import CommandService from "./services/CommandService";
5
+ import { ConfigurationService } from "./services";
6
+ import ToolRegistryService from "./services/ToolRegistryService";
7
+ import {
8
+ COMMAND_SERVICE,
9
+ CONFIGURATION_SERVICE,
10
+ TOOL_REGISTRY_SERVICE,
11
+ } from "./services";
12
+
13
+ interface ExtensionMetadata {
14
+ name: string;
15
+ }
16
+
17
+ interface Extension {
18
+ id: string;
19
+ metadata?: Partial<ExtensionMetadata>;
20
+
21
+ activate(context: ExtensionContext): void;
22
+ deactivate(context: ExtensionContext): void;
23
+ contribute?(): Record<string, any[]>;
24
+ }
25
+
26
+ class ExtensionRegistry extends Map<string, Extension> {}
27
+
28
+ class ExtensionManager {
29
+ private readonly context: ExtensionContext;
30
+ private extensionRegistry: ExtensionRegistry = new ExtensionRegistry();
31
+ private extensionDisposables: Map<string, Disposable[]> = new Map();
32
+
33
+ constructor(context: ExtensionContext) {
34
+ this.context = context;
35
+ }
36
+
37
+ register(extension: Extension) {
38
+ if (this.extensionRegistry.has(extension.id)) {
39
+ console.warn(
40
+ `Plugin "${extension.id}" already registered. It will be overwritten.`,
41
+ );
42
+ }
43
+
44
+ // Initialize disposables for this extension
45
+ this.extensionDisposables.set(extension.id, []);
46
+ const disposables = this.extensionDisposables.get(extension.id)!;
47
+
48
+ // Process declarative contributions
49
+ if (extension.contribute) {
50
+ for (const [pointId, items] of Object.entries(extension.contribute())) {
51
+ if (Array.isArray(items)) {
52
+ items.forEach((item, index) => {
53
+ const contributionId =
54
+ item.id ||
55
+ (item.command
56
+ ? item.command
57
+ : `${extension.id}.${pointId}.${index}`);
58
+ const contribution: Contribution = {
59
+ id: contributionId,
60
+ metadata: {
61
+ extensionId: extension.id,
62
+ ...item?.metadata,
63
+ },
64
+ data: item,
65
+ };
66
+ const disposable = this.context.contributions.register(
67
+ pointId,
68
+ contribution,
69
+ );
70
+
71
+ // Track contribution registration to unregister later
72
+ disposables.push(disposable);
73
+
74
+ const dispose = this.collectContribution(pointId, contribution);
75
+ if (dispose) {
76
+ disposables.push(dispose);
77
+ }
78
+ });
79
+ }
80
+ }
81
+ }
82
+
83
+ try {
84
+ this.extensionRegistry.set(extension.id, extension);
85
+ this.context.eventBus.emit("extension:register", extension);
86
+ } catch (error) {
87
+ console.error(
88
+ `Error in onCreate hook for plugin "${extension.id}":`,
89
+ error,
90
+ );
91
+ }
92
+
93
+ try {
94
+ extension.activate(this.context);
95
+ } catch (error) {
96
+ console.error(
97
+ `Error in onActivate hook for plugin "${extension.id}":`,
98
+ error,
99
+ );
100
+ }
101
+
102
+ console.log(`Plugin "${extension.id}" registered successfully`);
103
+ }
104
+
105
+ collectContribution(pointId: string, item: any): Disposable | undefined {
106
+ // If registering configurations, update ConfigurationService defaults
107
+ if (pointId === ContributionPointIds.CONFIGURATIONS) {
108
+ const configService = this.context.services.get<ConfigurationService>(
109
+ CONFIGURATION_SERVICE,
110
+ );
111
+ configService?.initializeDefaults([item.data]);
112
+ }
113
+ if (pointId === ContributionPointIds.COMMANDS && item.data.handler) {
114
+ const commandService =
115
+ this.context.services.get<CommandService>(COMMAND_SERVICE)!;
116
+
117
+ return commandService.registerCommand(item.id, item.data.handler);
118
+ }
119
+ if (pointId === ContributionPointIds.TOOLS) {
120
+ const toolRegistry = this.context.services.get<ToolRegistryService>(
121
+ TOOL_REGISTRY_SERVICE,
122
+ );
123
+ if (!toolRegistry) return;
124
+ return toolRegistry.registerTool(item.data);
125
+ }
126
+ }
127
+
128
+ unregister(name: string) {
129
+ const extension = this.extensionRegistry.get(name);
130
+ if (!extension) {
131
+ console.warn(`Plugin "${name}" not found.`);
132
+ return;
133
+ }
134
+
135
+ try {
136
+ extension.deactivate(this.context);
137
+ } catch (error) {
138
+ console.error(`Error in deactivate for plugin "${name}":`, error);
139
+ }
140
+
141
+ // Dispose all resources associated with this extension
142
+ const disposables = this.extensionDisposables.get(name);
143
+ if (disposables) {
144
+ disposables.forEach((d) => d.dispose());
145
+ this.extensionDisposables.delete(name);
146
+ }
147
+
148
+ this.extensionRegistry.delete(name);
149
+ console.log(`Plugin "${name}" unregistered`);
150
+ return true;
151
+ }
152
+
153
+ enable(name: string) {
154
+ const extension = this.extensionRegistry.get(name);
155
+ if (!extension) {
156
+ console.warn(`Plugin "${name}" not found.`);
157
+ return;
158
+ }
159
+ }
160
+
161
+ disable(name: string) {
162
+ const extension = this.extensionRegistry.get(name);
163
+ if (!extension) {
164
+ console.warn(`Plugin "${name}" not found.`);
165
+ return;
166
+ }
167
+ }
168
+
169
+ update() {}
170
+
171
+ destroy() {
172
+ const extensionNames = Array.from(this.extensionRegistry.keys());
173
+ extensionNames.forEach((name) => this.unregister(name));
174
+ }
175
+ }
176
+
177
+ export { Extension, ExtensionMetadata, ExtensionRegistry, ExtensionManager };