원클릭으로
event-ipc-integration
Pipeline instructions for creating events, subscribing via EventBus, and syncing with the Renderer (React) via IPC.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Pipeline instructions for creating events, subscribing via EventBus, and syncing with the Renderer (React) via IPC.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Use when adding or changing features that affect lifecycle phases, service startup/shutdown, EventBus/IPC boundaries, shared state ownership, background processes, or cross-module responsibilities.
MANDATORY rules for adding or changing any AppConfig field (data layer only — independent of whether a settings-screen UI is involved). Covers AppConfig type, CONFIG_METADATA, CONFIG_KEYS, DEFAULT_CONFIG registration and persistence model.
Use when changing anything under src/main/kakao/ (login/launch automation, PageHandler selectors, SecurityCenter, visibility policy, page dumps, maintenance detection) or the KakaoGames starter/UAC path (src/main/utils/uac/kakao-game-starter.ts, uac-migration.ts). Third-party-DOM selector policy and real-user blast radius rules.
Use when a user says a feature, bug fix, experiment, or follow-up can wait, should be done later, belongs on the roadmap/backlog, or asks to add/update roadmap items. Two tracks — user-visible product changes go to docs/Roadmap.md (CI-synced to GitHub Issue
Declarative pipeline for rendering and wiring settings-SCREEN UI items (settings-config.ts items, Context API hooks, no-hardcoding rule). For the underlying AppConfig data-layer registration, use config-management first.
Use this skill whenever debugging or visually verifying the POE2 launcher UI, Electron runtime errors, Vite dev-server behavior, Chrome DevTools attachment, screenshots, or CDP capture. This project is Windows-first; this skill prevents WSL/mock-browser verification mistakes by forcing pwsh npm run dev, launcher terminal logs, Chrome remote debugging, and real Electron screenshots.
| name | event-ipc-integration |
| description | Pipeline instructions for creating events, subscribing via EventBus, and syncing with the Renderer (React) via IPC. |
Target Audience: AI Agents Objective: When requested to create a new EventBus event that interacts with the Renderer (UI), strictly follow this end-to-end pipeline to ensure architectural consistency and type-safety.
File: src/main/events/types.ts
EventType enum.AppEvent Union type.export enum EventType {
// ... existing
MY_CUSTOM_EVENT = "DOMAIN:MY_CUSTOM_EVENT",
}
export interface MyCustomEvent {
type: EventType.MY_CUSTOM_EVENT;
payload: { status: string; message: string };
}
// ...existing members, then append the new interface:
export type AppEvent = ExistingEvents | MyCustomEvent;
File: src/main/events/handlers/MyCustomHandler.ts
Instead of calling mainWindow.webContents.send() randomly, create a dedicated EventHandler.
import { EventHandler, EventType, MyCustomEvent } from "../types";
export const MyCustomHandler: EventHandler<MyCustomEvent> = {
id: "MyCustomHandler",
targetEvent: EventType.MY_CUSTOM_EVENT,
handle: async (event, context) => {
// Safely emit to renderer
context.mainWindow?.webContents.send("app:my-custom-event", event.payload);
},
};
Note: Register the handler by adding it to CORE_EVENT_HANDLERS in
src/main/events/register-handlers.ts — do not call eventBus.register
ad-hoc from main.ts.
File: src/main/preload.ts
Inside contextBridge.exposeInMainWorld("electronAPI", { ... }):
CRITICAL: You MUST return a cleanup function containing ipcRenderer.off to prevent React from leaking memory during hot reloads or unmounts.
onMyCustomEvent: (callback: (data: { status: string; message: string }) => void) => {
const handler = (_event: Electron.IpcRendererEvent, data: { status: string; message: string }) => callback(data);
ipcRenderer.on("app:my-custom-event", handler);
// Return the auto-unsubscriber
return () => ipcRenderer.off("app:my-custom-event", handler);
},
File: src/shared/types.ts (or equivalent global type def file)
Ensure you add the function signature to the ElectronAPI interface so the Renderer compilation passes successfully.
Ensure to invoke the unsubscribe logic inside the useEffect cleanup hook.
useEffect(() => {
// Setup the listener
const unsubscribe = window.electronAPI.onMyCustomEvent((payload) => {
console.log(payload.message);
});
// Teardown the listener
return () => {
unsubscribe();
};
}, []);
If the Renderer triggers an action:
triggerMyAction: (data) => ipcRenderer.send("ui:my-action", data).main.ts or an IPC controller via ipcMain.on.ipcMain.on block. Instead, instantly delegate it to the EventBus:
ipcMain.on("ui:my-action", (_, data) => eventBus.emit(EventType.MY_ACTION, context, data));