Appearance
EventSource
EventSource는 메인 프로세스에서 렌더러로 이벤트를 push하는 경량 이벤트 버스다. contract의 forwards에 정의된 채널과 controller의 동명 메서드를 통해 프레임워크가 자동으로 webContents.send()를 호출한다.
EventSource<T>
Service가 도메인 이벤트를 발행하는 경량 이벤트 버스다.
ts
import { Injectable, EventSource } from '@repo/electron-ipc';
@Injectable()
class ThemeService {
readonly themeChanged = new EventSource<ThemeInfo>();
setTheme(theme: Theme) {
// ... 테마 적용 로직
this.themeChanged.emit(newThemeInfo);
}
}| 메서드 | 설명 |
|---|---|
emit(data) | 이벤트를 발행한다. 등록된 모든 리스너에 데이터를 전달한다 |
subscribe(listener) | 리스너를 등록하고 해제 함수를 반환한다 |
Controller 연결
contract에서 forward를 정의하고, controller에서 같은 이름의 메서드가 EventSource<T>를 반환하면 프레임워크가 자동으로 구독한다.
ts
// 1. Contract에 forward 선언
const appContract = contract({
handles: {},
forwards: {
onThemeChanged: forward<ThemeInfo>('theme:changed'),
},
});
// 2. Controller에서 동명 메서드로 EventSource 반환
@Controller(appContract)
class ThemeController {
private readonly theme = inject(ThemeService);
onThemeChanged() {
return this.theme.themeChanged; // EventSource<ThemeInfo>
}
}ControllerOf<typeof appContract>가 onThemeChanged()의 반환 타입을 EventSource<ThemeInfo>로 강제하므로 시그니처 mismatch는 IDE에서 잡힌다.
동작 흐름
onWindowAttach시점에 프레임워크가contract.forwards를 순회하며 controller의 동명 메서드를 호출해 EventSource를 얻는다- EventSource를
subscribe()하여 이벤트 발생 시webContents.send(channel, data)를 호출한다 - 윈도우
closed이벤트 시 구독이 자동 해제된다
이 패턴은 Service에서 OnWindowAttach 구현 + window 필드 + webContents.send() 직접 호출을 제거한다.
다음 단계
- Guards — IPC 요청 검증
- Contract System — contract로 preload/renderer 코드 자동 생성