@pooder/core 2.1.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.
@@ -1,8 +1,9 @@
1
1
  import Disposable from "../disposable";
2
2
  import EventBus from "../event";
3
- import { Service } from "../service";
3
+ import { Service, ServiceContext } from "../service";
4
4
  import ToolRegistryService from "./ToolRegistryService";
5
5
  import ToolSessionService from "./ToolSessionService";
6
+ import { TOOL_REGISTRY_SERVICE, TOOL_SESSION_SERVICE } from "./tokens";
6
7
 
7
8
  export interface ToolSwitchContext {
8
9
  from: string | null;
@@ -26,6 +27,12 @@ interface GuardItem {
26
27
  priority: number;
27
28
  }
28
29
 
30
+ interface WorkbenchServiceDependencies {
31
+ eventBus?: EventBus;
32
+ toolRegistry?: ToolRegistryService;
33
+ sessionService?: ToolSessionService;
34
+ }
35
+
29
36
  export default class WorkbenchService implements Service {
30
37
  private _activeToolId: string | null = null;
31
38
  private eventBus?: EventBus;
@@ -33,7 +40,27 @@ export default class WorkbenchService implements Service {
33
40
  private sessionService?: ToolSessionService;
34
41
  private guards: GuardItem[] = [];
35
42
 
36
- init() {}
43
+ constructor(dependencies: WorkbenchServiceDependencies = {}) {
44
+ this.eventBus = dependencies.eventBus;
45
+ this.toolRegistry = dependencies.toolRegistry;
46
+ this.sessionService = dependencies.sessionService;
47
+ }
48
+
49
+ init(context: ServiceContext) {
50
+ this.eventBus ??= context.eventBus;
51
+ this.toolRegistry ??= context.get(TOOL_REGISTRY_SERVICE);
52
+ this.sessionService ??= context.get(TOOL_SESSION_SERVICE);
53
+
54
+ if (!this.eventBus) {
55
+ throw new Error("WorkbenchService requires EventBus.");
56
+ }
57
+ if (!this.toolRegistry) {
58
+ throw new Error("WorkbenchService requires ToolRegistryService.");
59
+ }
60
+ if (!this.sessionService) {
61
+ throw new Error("WorkbenchService requires ToolSessionService.");
62
+ }
63
+ }
37
64
 
38
65
  dispose() {
39
66
  this.guards = [];
@@ -82,11 +109,15 @@ export default class WorkbenchService implements Service {
82
109
  id: string | null,
83
110
  options?: { reason?: string },
84
111
  ): Promise<ToolSwitchResult> {
112
+ const eventBus = this.getEventBus();
113
+ const toolRegistry = this.getToolRegistry();
114
+ const sessionService = this.getSessionService();
115
+
85
116
  if (this._activeToolId === id) {
86
117
  return { ok: true, from: this._activeToolId, to: id };
87
118
  }
88
119
 
89
- if (id && this.toolRegistry && !this.toolRegistry.hasTool(id)) {
120
+ if (id && !toolRegistry.hasTool(id)) {
90
121
  return {
91
122
  ok: false,
92
123
  from: this._activeToolId,
@@ -103,7 +134,7 @@ export default class WorkbenchService implements Service {
103
134
 
104
135
  const guardAllowed = await this.runGuards(context);
105
136
  if (!guardAllowed) {
106
- this.eventBus?.emit("tool:switch:blocked", {
137
+ eventBus.emit("tool:switch:blocked", {
107
138
  ...context,
108
139
  reason: "blocked-by-guard",
109
140
  });
@@ -115,12 +146,10 @@ export default class WorkbenchService implements Service {
115
146
  };
116
147
  }
117
148
 
118
- if (context.from && this.sessionService) {
119
- const leaveResult = await this.sessionService.handleBeforeLeave(
120
- context.from,
121
- );
149
+ if (context.from) {
150
+ const leaveResult = await sessionService.handleBeforeLeave(context.from);
122
151
  if (leaveResult.decision === "blocked") {
123
- this.eventBus?.emit("tool:switch:blocked", {
152
+ eventBus.emit("tool:switch:blocked", {
124
153
  ...context,
125
154
  reason: leaveResult.reason || "session-blocked",
126
155
  });
@@ -131,21 +160,21 @@ export default class WorkbenchService implements Service {
131
160
  reason: leaveResult.reason || "session-blocked",
132
161
  };
133
162
  }
134
- this.sessionService.deactivateSession(context.from);
163
+ sessionService.deactivateSession(context.from);
135
164
  }
136
165
 
137
- if (id && this.sessionService && this.toolRegistry) {
138
- const tool = this.toolRegistry.getTool(id);
166
+ if (id) {
167
+ const tool = toolRegistry.getTool(id);
139
168
  if (tool?.interaction === "session" && tool.session?.autoBegin !== false) {
140
- await this.sessionService.begin(id);
169
+ await sessionService.begin(id);
141
170
  }
142
171
  }
143
172
 
144
173
  const previous = this._activeToolId;
145
174
  this._activeToolId = id;
146
175
  const reason = options?.reason;
147
- this.eventBus?.emit("tool:activated", { id, previous, reason });
148
- this.eventBus?.emit("tool:switch", { from: previous, to: id, reason });
176
+ eventBus.emit("tool:activated", { id, previous, reason });
177
+ eventBus.emit("tool:switch", { from: previous, to: id, reason });
149
178
  return { ok: true, from: previous, to: id };
150
179
  }
151
180
 
@@ -156,4 +185,25 @@ export default class WorkbenchService implements Service {
156
185
  async deactivate(): Promise<ToolSwitchResult> {
157
186
  return await this.switchTool(null, { reason: "deactivate" });
158
187
  }
188
+
189
+ private getEventBus(): EventBus {
190
+ if (!this.eventBus) {
191
+ throw new Error("WorkbenchService is not initialized.");
192
+ }
193
+ return this.eventBus;
194
+ }
195
+
196
+ private getToolRegistry(): ToolRegistryService {
197
+ if (!this.toolRegistry) {
198
+ throw new Error("WorkbenchService is not initialized.");
199
+ }
200
+ return this.toolRegistry;
201
+ }
202
+
203
+ private getSessionService(): ToolSessionService {
204
+ if (!this.sessionService) {
205
+ throw new Error("WorkbenchService is not initialized.");
206
+ }
207
+ return this.sessionService;
208
+ }
159
209
  }
@@ -3,6 +3,14 @@ import ConfigurationService from "./ConfigurationService";
3
3
  import ToolRegistryService from "./ToolRegistryService";
4
4
  import ToolSessionService from "./ToolSessionService";
5
5
  import WorkbenchService from "./WorkbenchService";
6
+ import {
7
+ COMMAND_SERVICE,
8
+ CONFIGURATION_SERVICE,
9
+ CORE_SERVICE_TOKENS,
10
+ TOOL_REGISTRY_SERVICE,
11
+ TOOL_SESSION_SERVICE,
12
+ WORKBENCH_SERVICE,
13
+ } from "./tokens";
6
14
 
7
15
  export {
8
16
  CommandService,
@@ -10,4 +18,10 @@ export {
10
18
  ToolRegistryService,
11
19
  ToolSessionService,
12
20
  WorkbenchService,
21
+ COMMAND_SERVICE,
22
+ CONFIGURATION_SERVICE,
23
+ TOOL_REGISTRY_SERVICE,
24
+ TOOL_SESSION_SERVICE,
25
+ WORKBENCH_SERVICE,
26
+ CORE_SERVICE_TOKENS,
13
27
  };
@@ -0,0 +1,27 @@
1
+ import { createServiceToken } from "../service";
2
+ import type CommandService from "./CommandService";
3
+ import type ConfigurationService from "./ConfigurationService";
4
+ import type ToolRegistryService from "./ToolRegistryService";
5
+ import type ToolSessionService from "./ToolSessionService";
6
+ import type WorkbenchService from "./WorkbenchService";
7
+
8
+ export const COMMAND_SERVICE = createServiceToken<CommandService>(
9
+ "CommandService",
10
+ );
11
+ export const CONFIGURATION_SERVICE = createServiceToken<ConfigurationService>(
12
+ "ConfigurationService",
13
+ );
14
+ export const TOOL_REGISTRY_SERVICE =
15
+ createServiceToken<ToolRegistryService>("ToolRegistryService");
16
+ export const TOOL_SESSION_SERVICE =
17
+ createServiceToken<ToolSessionService>("ToolSessionService");
18
+ export const WORKBENCH_SERVICE =
19
+ createServiceToken<WorkbenchService>("WorkbenchService");
20
+
21
+ export const CORE_SERVICE_TOKENS = {
22
+ COMMAND: COMMAND_SERVICE,
23
+ CONFIGURATION: CONFIGURATION_SERVICE,
24
+ TOOL_REGISTRY: TOOL_REGISTRY_SERVICE,
25
+ TOOL_SESSION: TOOL_SESSION_SERVICE,
26
+ WORKBENCH: WORKBENCH_SERVICE,
27
+ } as const;