Skip to content

Commit 08dea95

Browse files
refactor(Cocoon/Service): Migrate WebViewPanel IPC handlers to pure Effect-TS patterns
- Rewrote imperative IPC handlers using Effect.gen for proper Effect-TS integration, ensuring consistent error handling and resource management - Simplified state access patterns by directly yielding ActivePanels Ref instead of nested Effect pipelines - Converted disposal operations to non-blocking effects using Effect.runFork to align with Mountain's async architecture - Removed redundant LogService dependency and sync Effect executions to improve Cocoon's declarative service layer - Updated panel serialization stub to return Effect.succeed for architectural consistency - Aligns with Land's core principle of using Effect-TS for all Cocoon-side operations, maintaining strict separation between imperative Node.js APIs and declarative effectful code - Ensures WebViewPanel lifecycle events follow the same gRPC/IPC patterns as other implemented workflows
1 parent e1c4095 commit 08dea95

File tree

1 file changed

+49
-63
lines changed

1 file changed

+49
-63
lines changed

Source/Service/WebViewPanel/Definition.ts

Lines changed: 49 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -20,57 +20,47 @@ import { Log } from "../Log.js";
2020
import type { Interface } from "./Service.js";
2121
import { WebViewPanelImplementation } from "./WebViewPanelImplementation.js";
2222

23-
export const Definition = Effect.gen(function* (_) {
24-
const IPCService = yield* _(IPC.Tag);
25-
const LogService = yield* _(Log.Tag);
26-
const ActivePanels = yield* _(
27-
Ref.make(new Map<string, WebViewPanelImplementation>()),
23+
export const Definition = Effect.gen(function* () {
24+
const IPCService = yield* IPC.Tag;
25+
const ActivePanels = yield* Ref.make(
26+
new Map<string, WebViewPanelImplementation>(),
2827
);
2928

30-
// --- RPC Handlers for events FROM Mountain ---
31-
IPCService.RegisterInvokeHandler("$onDidDisposeWebview", ([handle]) => {
32-
const panel = Ref.get(ActivePanels).pipe(
33-
Effect.map((m) => m.get(handle)),
34-
Effect.runSync,
35-
);
36-
if (panel) {
37-
panel.dispose();
38-
}
39-
return Promise.resolve(undefined);
40-
});
41-
IPCService.RegisterInvokeHandler(
42-
"$onDidReceiveMessage",
43-
([handle, message]) => {
44-
const panel = Ref.get(ActivePanels).pipe(
45-
Effect.map((m) => m.get(handle)),
46-
Effect.runSync,
47-
);
29+
IPCService.RegisterInvokeHandler("$onDidDisposeWebview", ([handle]) =>
30+
Effect.gen(function* () {
31+
const panel = (yield* Ref.get(ActivePanels)).get(handle);
4832
if (panel) {
49-
(panel.webview as any).fireDidReceiveMessage(message);
33+
panel.dispose();
5034
}
51-
return Promise.resolve(undefined);
52-
},
35+
}),
36+
);
37+
38+
IPCService.RegisterInvokeHandler(
39+
"$onDidReceiveMessage",
40+
([handle, message]) =>
41+
Effect.gen(function* () {
42+
const panel = (yield* Ref.get(ActivePanels)).get(handle);
43+
if (panel) {
44+
(panel.webview as any).fireDidReceiveMessage(message);
45+
}
46+
}),
5347
);
48+
5449
IPCService.RegisterInvokeHandler(
5550
"$onDidChangeWebviewPanelViewState",
56-
([handle, newState]) => {
57-
const panel = Ref.get(ActivePanels).pipe(
58-
Effect.map((m) => m.get(handle)),
59-
Effect.runSync,
60-
);
61-
if (panel) {
62-
panel._updateViewState(newState);
63-
}
64-
return Promise.resolve(undefined);
65-
},
51+
([handle, newState]) =>
52+
Effect.gen(function* () {
53+
const panel = (yield* Ref.get(ActivePanels)).get(handle);
54+
if (panel) {
55+
panel._updateViewState(newState);
56+
}
57+
}),
6658
);
59+
6760
IPCService.RegisterInvokeHandler(
6861
"$deserializeWebviewPanel",
69-
([handle, viewType, title, state, options, contentOptions]) => {
70-
// This requires looking up the correct serializer and calling it.
71-
// This is a complex flow that is stubbed for now.
72-
return Promise.resolve(undefined);
73-
},
62+
([handle, viewType, title, state, options, contentOptions]) =>
63+
Effect.succeed(undefined), // Stubbed
7464
);
7565

7666
const ServiceImplementation: Interface = {
@@ -81,7 +71,7 @@ export const Definition = Effect.gen(function* (_) {
8171
ShowOptions,
8272
Options: WebviewPanelOptions & WebviewOptions = {},
8373
) =>
84-
Effect.gen(function* (_) {
74+
Effect.gen(function* () {
8575
const handle = generateUuid();
8676
const ViewColumnValue =
8777
typeof ShowOptions === "object"
@@ -105,22 +95,22 @@ export const Definition = Effect.gen(function* (_) {
10595
Options,
10696
);
10797

108-
yield* _(
109-
IPCService.SendRequest<string>("$createWebviewPanel", [
110-
handle,
111-
ViewType,
112-
Title,
113-
ShowOptionsDTO,
114-
PanelOptionsDTO,
115-
ContentOptionsDTO,
116-
]),
117-
);
98+
yield* IPCService.SendRequest<string>("$createWebviewPanel", [
99+
handle,
100+
ViewType,
101+
Title,
102+
ShowOptionsDTO,
103+
PanelOptionsDTO,
104+
ContentOptionsDTO,
105+
]);
118106

119107
const onDispose = () => {
120-
Ref.update(
121-
ActivePanels,
122-
(map) => (map.delete(handle), map),
123-
).pipe(Effect.runSync);
108+
Effect.runFork(
109+
Ref.update(
110+
ActivePanels,
111+
(map) => (map.delete(handle), map),
112+
),
113+
);
124114
};
125115

126116
const Panel = new WebViewPanelImplementation(
@@ -133,22 +123,18 @@ export const Definition = Effect.gen(function* (_) {
133123
Options,
134124
ViewColumnValue,
135125
);
136-
yield* _(
137-
Ref.update(ActivePanels, (map) => map.set(handle, Panel)),
126+
yield* Ref.update(ActivePanels, (map) =>
127+
map.set(handle, Panel),
138128
);
139-
140129
return Panel;
141130
}),
142131

143132
RegisterWebviewPanelSerializer: (Extension, ViewType, Serializer) =>
144133
Effect.sync(() => {
145134
IPCService.SendNotification("$registerWebviewPanelSerializer", [
146135
ViewType,
147-
{
148-
// options for the serializer
149-
},
136+
{},
150137
]);
151-
// The actual registration would be stored and used by the $deserializeWebviewPanel handler
152138
return new Disposable(() => {
153139
IPCService.SendNotification(
154140
"$unregisterWebviewPanelSerializer",

0 commit comments

Comments
 (0)