Appearance
API Reference
@repo/electron-ipc가 export하는 모든 심볼의 시그니처와 설명.
엔트리포인트
| 경로 | 용도 | Electron 의존성 |
|---|---|---|
@repo/electron-ipc | 메인 프로세스 (DI, 데코레이터, createApp) | O |
@repo/electron-ipc/contract | contract 정의 (contract, handle, forward, 타입) | X |
@repo/electron-ipc/bridge | preload (createBridge) | O |
@repo/electron-ipc/service | 렌더러 (createService) | X |
데코레이터
Injectable()
DI 컨테이너에 등록 가능한 서비스를 표시한다.
ts
function Injectable(): (target: Constructor, context: ClassDecoratorContext) => voidController(contract)
IPC 핸들러를 포함하는 클래스를 표시한다. 두 가지를 동시에 수행한다:
- 클래스 형태 강제 — 클래스가
ControllerOf<C>를 만족하지 않으면 컴파일 에러. 메서드 누락이나 시그니처 mismatch가 IDE에서 잡힌다. - 자동 채널 바인딩 — 부트스트랩 시
contract.handles와contract.forwards를 순회해 동일 이름의 메서드를 IPC 채널에 바인딩한다.
ts
function Controller<C extends Contract>(
contract: C
): <T extends Constructor<ControllerOf<C>>>(
target: T,
context: ClassDecoratorContext<T>
) => void
function Controller(
options?: ControllerOptions
): (target: Constructor, context: ClassDecoratorContext) => void매개변수:
| 이름 | 타입 | 설명 |
|---|---|---|
contract | Contract | 도메인 contract. 클래스 형태와 채널 바인딩에 사용 |
options | ControllerOptions | 옵셔널 메타데이터 폼 (예: { api: string }). contract와 함께 사용하지 않는다 |
WARNING
createApp은 contract 없이 등록된 controller를 거부한다. @Controller(contract) 형태로 사용한다.
UsePipes(...pipes)
핸들러 메서드에 Pipe를 적용한다. 글로벌 Pipe 이후에 실행된다.
ts
function UsePipes(...pipes: IpcPipe[]): (target: IpcHandler, context: ClassMethodDecoratorContext) => void매개변수:
| 이름 | 타입 | 설명 |
|---|---|---|
pipes | IpcPipe[] | 핸들러에 적용할 Pipe 인스턴스 |
Module(metadata)
provider와 controller를 모듈 단위로 그룹화한다.
ts
function Module(metadata: ModuleMetadata): (target: Constructor, context: ClassDecoratorContext) => void매개변수:
| 이름 | 타입 | 설명 |
|---|---|---|
metadata | ModuleMetadata | 모듈 구성 정보 |
Contract 헬퍼 (@repo/electron-ipc/contract)
handle(channel, options?)
IPC invoke 채널의 타입을 정의한다. options.schema를 전달하면 extractSchemaMap()으로 자동 추출할 수 있다.
ts
function handle<A extends unknown[], R>(
channel: string,
options?: { schema?: Parseable },
): HandleDef<A, R>제네릭:
| 이름 | 설명 |
|---|---|
A | 인자 타입 (tuple) |
R | 반환 타입. void이면 service에서 true | null 반환 |
매개변수:
| 이름 | 타입 | 설명 |
|---|---|---|
channel | string | IPC 채널 이름 |
options.schema | Parseable | 선택. 인자 검증/파싱에 사용할 스키마 (Zod 등) |
forward(channel)
IPC 이벤트 채널의 타입을 정의한다.
ts
function forward<T>(channel: string): ForwardDef<T>제네릭:
| 이름 | 설명 |
|---|---|
T | 이벤트 데이터 타입 |
contract(def)
handle과 forward를 하나의 도메인 contract로 묶는다.
ts
function contract<H, F>(def: { handles: H; forwards?: F }): Contract<H, F>클래스
Container
싱글톤 레지스트리. provider를 등록하고 lifecycle을 관리한다.
ts
class Container {
constructor(options?: ContainerOptions)
register(token: Constructor): void
resolve<T>(token: Constructor<T>): T
createInstance<T>(cls: Constructor<T>): T
resolveAll(): void
initAll(): void
attachWindowAll(window: BrowserWindow): void
disposeAll(): void
}| 메서드 | 설명 |
|---|---|
register(token) | @Injectable 표시된 클래스를 등록한다 |
resolve(token) | 싱글톤 인스턴스를 반환한다. 첫 호출 시 생성한다 |
createInstance(cls) | 레지스트리에 등록하지 않는 일회성 인스턴스를 생성한다 |
resolveAll() | 등록된 모든 provider를 등록 순서대로 eagerly resolve한다 |
initAll() | OnInit.onInit()을 등록 순서대로 호출한다 |
createMainWindow() | OnMainWindowCreate 구현체의 onMainWindowCreate()를 호출하여 BrowserWindow를 반환한다. 구현체가 정확히 1개가 아니면 throw한다 |
attachWindowAll(window) | OnWindowAttach.onWindowAttach()을 등록 순서대로 호출한다 |
disposeAll() | OnDispose.onDispose()를 등록 순서대로 호출한다 |
EventSource<T>
Service가 도메인 이벤트를 발행하는 경량 이벤트 버스. contract의 forward 메서드가 반환한다.
ts
class EventSource<T = void> {
emit(data: T): void
subscribe(listener: (data: T) => void): () => void
}| 메서드 | 설명 |
|---|---|
emit(data) | 이벤트를 발행한다. 등록된 모든 리스너에 데이터를 전달한다 |
subscribe(listener) | 리스너를 등록하고 해제 함수를 반환한다 |
SenderGuard
IPC 메시지 발신자가 등록된 윈도우의 webContents인지 검증하는 내장 Guard.
ts
class SenderGuard implements IpcGuard {
canActivate(ctx: IpcContext): boolean
}함수
createApp(config)
모듈을 부트스트랩하고 IPC 핸들러를 등록하는 팩토리. 반환된 객체의 start()로 앱을 시작한다.
ts
function createApp(config: AppConfig): { start(): BrowserWindow }자세한 설정은 AppConfig를 참고한다.
extractSchemaMap(contracts) — @repo/electron-ipc/contract
contracts에서 channel → schema Map을 자동 추출한다. handle()에 schema 옵션을 전달한 채널만 포함된다.
ts
function extractSchemaMap(
contracts: Record<string, Contract>,
): Map<string, Parseable>createBridge(contracts) — @repo/electron-ipc/bridge
contracts 맵에서 preload bridge 객체를 생성한다. 각 handle은 ipcRenderer.invoke(), 각 forward는 ipcRenderer.on()으로 바인딩된다.
ts
function createBridge<Cs extends Record<string, Contract>>(
contracts: Cs
): BridgeAPI<Cs>createService(api, contracts) — @repo/electron-ipc/service
bridge API를 감싸서 IpcResponse를 자동 언래핑하는 service 객체를 생성한다.
ts
function createService<Cs extends Record<string, Contract>>(
api: BridgeAPI<Cs>,
contracts: Cs
): ServiceAPI<Cs>언래핑 규칙:
- handle (데이터 반환): 성공 시
data, 실패 시null - handle (void 반환): 성공 시
true, 실패 시null - forward: 패스스루
inject(token)
클래스 필드 이니셜라이저에서 의존성을 주입한다. Container의 인스턴스 생성 컨텍스트 안에서만 호출할 수 있다.
ts
function inject<T>(token: Constructor<T>): T매개변수:
| 이름 | 타입 | 설명 |
|---|---|---|
token | Constructor<T> | resolve할 서비스 클래스 |
인터페이스
AppConfig
createApp()에 전달하는 설정 객체. 자세한 설명은 AppConfig 레퍼런스를 참고한다.
ts
interface AppConfig {
modules: Constructor[]
guards?: IpcGuard[]
pipes?: IpcPipe[]
exceptionHandlers?: IpcExceptionHandler[]
logger?: AppLogger
onError?: (name: string, error: unknown) => void
}메인 윈도우 생성은 AppConfig 필드가 아니라 OnMainWindowCreate 인터페이스를 구현한 provider가 담당한다 (Lifecycle 참고).
AppLogger
AppConfig.logger에 전달하는 로거 인터페이스.
ts
interface AppLogger {
info(message: string): void
}ContainerOptions
Container 생성자에 전달하는 옵션.
ts
interface ContainerOptions {
onError?: (name: string, error: unknown) => void
}IpcContext
Guard와 ExceptionHandler에 전달되는 IPC 요청 컨텍스트.
ts
interface IpcContext {
event: IpcMainInvokeEvent
channel: string
window: BrowserWindow
args: unknown[]
}IpcGuard
IPC 요청 검증 인터페이스.
ts
interface IpcGuard {
canActivate(ctx: IpcContext): boolean | Promise<boolean>
}IpcPipe
IPC 인자 변환/검증 인터페이스. Guard 이후, 핸들러 이전에 실행된다.
ts
interface IpcPipe {
transform(args: unknown[], ctx: IpcContext): unknown[] | Promise<unknown[]>
}IpcExceptionHandler
IPC 에러 처리 인터페이스. catch()는 IpcError를 반환한다. 프레임워크가 이를 IpcResponse의 { ok: false, error } 형태로 래핑하여 렌더러에 전달한다.
ts
interface IpcExceptionHandler {
catch(error: unknown, ctx: IpcContext): IpcError
}OnInit
윈도우 생성 전 초기화 lifecycle.
ts
interface OnInit {
onInit(): void
}OnMainWindowCreate
메인 BrowserWindow 생성 lifecycle. 앱당 정확히 하나의 provider만 구현해야 한다.
ts
interface OnMainWindowCreate {
onMainWindowCreate(): BrowserWindow
}OnWindowAttach
윈도우 생성 후 lifecycle.
ts
interface OnWindowAttach {
onWindowAttach(window: BrowserWindow): void
}OnDispose
윈도우 종료 시 정리 lifecycle.
ts
interface OnDispose {
onDispose(): void
}타입
Parseable
Zod 의존 없이 parse(data) 호출만 요구하는 인터페이스. handle()의 schema 옵션에 전달한다.
ts
interface Parseable {
parse(data: unknown): unknown
}HandleDef<A, R>
handle() 함수가 반환하는 handle 정의 타입.
ts
type HandleDef<A extends unknown[] = unknown[], R = unknown> = {
readonly _tag: 'handle'
readonly channel: string
readonly schema?: Parseable // 인자 검증/파싱 스키마
readonly _args: A // 타입 추론 전용
readonly _return: R // 타입 추론 전용
}ForwardDef<T>
forward() 함수가 반환하는 forward 정의 타입.
ts
type ForwardDef<T = unknown> = {
readonly _tag: 'forward'
readonly channel: string
readonly _data: T // 타입 추론 전용
}Contract<H, F>
contract() 함수가 반환하는 도메인 contract 타입.
ts
type Contract<H, F> = {
readonly handles: H
readonly forwards: F
}BridgeAPI<Cs>
contracts 맵에서 preload bridge API 타입을 추출한다.
ts
type BridgeAPI<Cs extends Record<string, Contract>> = {
[K in keyof Cs]: SingleBridgeAPI<Cs[K]>
}- handle →
(...args: A) => Promise<IpcResponse<R>> - forward →
(callback: (data: T) => void) => () => void
ServiceAPI<Cs>
contracts 맵에서 렌더러 service API 타입을 추출한다. IpcResponse가 자동 언래핑된다.
ts
type ServiceAPI<Cs extends Record<string, Contract>> = {
[K in keyof Cs]: SingleServiceAPI<Cs[K]>
}- handle (R이 데이터) →
(...args: A) => Promise<R | null> - handle (R이 void) →
(...args: A) => Promise<true | null> - forward →
(callback: (data: T) => void) => () => void
IpcError
IPC 에러를 표현하는 구조체.
ts
type IpcError = { code: string; message: string }IpcResponse<T>
IPC 핸들러 응답의 discriminated union. createApp()이 모든 핸들러 응답을 이 형태로 자동 래핑한다.
ts
type IpcResponse<T> =
| { ok: true; data: T }
| { ok: false; error: IpcError }렌더러에서는 createService()가 자동 언래핑하므로 직접 다룰 필요가 없다.
ModuleMetadata
@Module() 데코레이터에 전달하는 모듈 구성 정보.
ts
type ModuleMetadata = {
providers: Constructor[]
controllers: Constructor[]
}ControllerOptions
@Controller() 데코레이터에 전달하는 옵션.
ts
type ControllerOptions = {
api?: string
}ControllerOf<C>
Contract에서 controller가 만족해야 할 클래스 형태를 추출한다. @Controller(contract)가 내부적으로 사용하여 클래스 시그니처를 강제한다.
handles[K]→(...args: A) => R | Promise<R>forwards[K]→() => EventSource<T>
ts
type ControllerOf<C extends Contract> = {
[K in keyof C['handles']]: (
...args: C['handles'][K]['_args']
) => C['handles'][K]['_return'] | Promise<C['handles'][K]['_return']>
} & {
[K in keyof C['forwards']]: () => EventSource<C['forwards'][K]['_data']>
}HandleEntry
contract에서 추출되는 채널-메서드 매핑 정보. 프레임워크 내부에서 사용한다.
ts
type HandleEntry = {
channel: string
methodKey: string
pipes?: IpcPipe[]
}ForwardEntry
contract에서 추출되는 forward 채널-메서드 매핑 정보. 프레임워크 내부에서 사용한다.
ts
type ForwardEntry = {
channel: string
methodKey: string
}IpcHandler
IPC 핸들러 함수 타입.
ts
type IpcHandler = (...args: any[]) => unknown | Promise<unknown>내부 유틸리티 함수
데코레이터 메타데이터를 조회하는 함수. 프레임워크 내부에서 사용하지만 export되어 있다.
isInjectable(cls)
클래스에 @Injectable() 데코레이터가 적용되었는지 확인한다.
ts
function isInjectable(cls: Constructor): booleangetControllerContract(cls)
@Controller()에 전달된 contract를 반환한다. createApp이 채널 바인딩에 사용한다.
ts
function getControllerContract(cls: Constructor): Contract | undefinedgetControllerMethodPipes(cls)
@UsePipes로 등록된 메서드별 pipe 맵을 반환한다.
ts
function getControllerMethodPipes(cls: Constructor): Map<string, IpcPipe[]>getControllerOptions(cls)
@Controller() 클래스의 옵션을 반환한다.
ts
function getControllerOptions(cls: Constructor): ControllerOptions | undefinedgetModuleMetadata(cls)
@Module() 클래스의 메타데이터를 반환한다.
ts
function getModuleMetadata(cls: Constructor): ModuleMetadata | undefined