콘텐츠로 이동

채널

상태가 왜 이런 방식으로 모델링되는지에 대한 전체 설명은 핵심 개념 → 채널 & 상태를 보세요. 이 페이지는 간결한 시그니처 레퍼런스예요.

export interface Channel<V, U = V> {
readonly "~value": V;
readonly "~update": U;
readonly reduce: (current: V, update: U) => V;
readonly initial: () => V;
}
export type StateOf<C> = { readonly [K in keyof C]: C[K] extends Channel<infer V, any> ? V : never };
export function lastChannel<T>(init: T): Channel<T, T>;

덮어쓰기 시맨틱이에요. 업데이트마다 현재 값을 새 값으로 대체해요.

const review = lastChannel<ReviewResult | null>(null);
export function listChannel<T>(): Channel<readonly T[], T | readonly T[]>;

추가 시맨틱이에요. 단일 항목이든 배열이든 받아서 뒤에 이어 붙여요. []에서 시작해요.

const transcript = listChannel<Msg>();
export interface InputChannel<T> extends Channel<T, T> {
readonly "~input": true;
}
export function inputChannel<T>(): InputChannel<T>;

lastChannel과 같은 덮어쓰기 시맨틱이지만, 정적인 init 값이 없어요. 대신 team() 실행이 실제로 호출될 때 받는 입력으로 초깃값이 채워져요. "~input": true로 브랜딩돼 있어서, TeamInputOf<State>가 팀의 state 레코드에서 이 채널들만 골라내 실행의 입력 형태를 유도할 수 있어요.

export type TeamInputOf<State> = {
readonly [K in keyof State as State[K] extends InputChannel<any> ? K : never]:
State[K] extends InputChannel<infer T> ? T : never;
};
const issue = inputChannel<Issue>();
export const END: "~end" = "~end";
export type END = typeof END;

workflow().branch/.edge 대상이나 team().router가 실행을 끝내기 위해 반환하는 센티널이에요.