Skip to content

API Reference

@repo/electron-ipc가 export하는 모든 심볼의 시그니처와 설명.

엔트리포인트

경로용도Electron 의존성
@repo/electron-ipc메인 프로세스 (DI, 데코레이터, createApp)O
@repo/electron-ipc/contractcontract 정의 (contract, handle, forward, 타입)X
@repo/electron-ipc/bridgepreload (createBridge)O
@repo/electron-ipc/service렌더러 (createService)X

데코레이터

Injectable()

DI 컨테이너에 등록 가능한 서비스를 표시한다.

ts
function Injectable(): (target: Constructor, context: ClassDecoratorContext) => void

Controller(contract)

IPC 핸들러를 포함하는 클래스를 표시한다. 두 가지를 동시에 수행한다:

  1. 클래스 형태 강제 — 클래스가 ControllerOf<C>를 만족하지 않으면 컴파일 에러. 메서드 누락이나 시그니처 mismatch가 IDE에서 잡힌다.
  2. 자동 채널 바인딩 — 부트스트랩 시 contract.handlescontract.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

매개변수:

이름타입설명
contractContract도메인 contract. 클래스 형태와 채널 바인딩에 사용
optionsControllerOptions옵셔널 메타데이터 폼 (예: { api: string }). contract와 함께 사용하지 않는다

WARNING

createApp은 contract 없이 등록된 controller를 거부한다. @Controller(contract) 형태로 사용한다.

UsePipes(...pipes)

핸들러 메서드에 Pipe를 적용한다. 글로벌 Pipe 이후에 실행된다.

ts
function UsePipes(...pipes: IpcPipe[]): (target: IpcHandler, context: ClassMethodDecoratorContext) => void

매개변수:

이름타입설명
pipesIpcPipe[]핸들러에 적용할 Pipe 인스턴스

Module(metadata)

provider와 controller를 모듈 단위로 그룹화한다.

ts
function Module(metadata: ModuleMetadata): (target: Constructor, context: ClassDecoratorContext) => void

매개변수:

이름타입설명
metadataModuleMetadata모듈 구성 정보

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 반환

매개변수:

이름타입설명
channelstringIPC 채널 이름
options.schemaParseable선택. 인자 검증/파싱에 사용할 스키마 (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

매개변수:

이름타입설명
tokenConstructor<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): boolean

getControllerContract(cls)

@Controller()에 전달된 contract를 반환한다. createApp이 채널 바인딩에 사용한다.

ts
function getControllerContract(cls: Constructor): Contract | undefined

getControllerMethodPipes(cls)

@UsePipes로 등록된 메서드별 pipe 맵을 반환한다.

ts
function getControllerMethodPipes(cls: Constructor): Map<string, IpcPipe[]>

getControllerOptions(cls)

@Controller() 클래스의 옵션을 반환한다.

ts
function getControllerOptions(cls: Constructor): ControllerOptions | undefined

getModuleMetadata(cls)

@Module() 클래스의 메타데이터를 반환한다.

ts
function getModuleMetadata(cls: Constructor): ModuleMetadata | undefined