알림 동작
상태 저장과 전달
업데이트는 현재 미들웨어 경로를 거칩니다. Object.is로 다른 값이면 즉시 저장하고, 그 값과 당시 구독 목록을 알림 기록으로 보관합니다. 알림은 동기 FIFO 순서로 처리하며 timer, microtask, batching을 사용하지 않습니다.
동일한 참조, 같은 값을 반환하는 updater, next를 호출하지 않는 미들웨어는 알림을 만들지 않습니다. 미들웨어는 바깥에서 안쪽 순서로 실행하며, 일반적인 알림은 next 안에서 실행되어 그 뒤의 미들웨어 코드보다 먼저 처리됩니다.
중첩 업데이트
1을 전달하는 중 리스너가 2를 저장하면 나머지 selector는 1을 받은 다음 2를 받습니다. Selector는 기록한 상태로 평가하며 다음 선택값과 이전 선택값을 전달합니다. getState()는 이전 기록을 전달하는 중에도 가장 최신 저장값을 읽습니다. 일반 subscribe는 인자가 없는 변경 신호입니다.
새 구독은 등록 전에 만들어진 기록을 받지 않습니다. 해제는 즉시 적용되며 반복 호출해도 안전합니다. 기록에 포함되어 있어도 해제된 구독은 건너뜁니다. 같은 콜백을 두 번 등록하면 서로 독립적인 구독을 만듭니다.
FIFO 전달은 재귀적인 스택 증가를 막지만 논리적인 무한 업데이트까지 막지는 않습니다. 리스너에서 갱신한다면 종료 조건이 필요합니다.
오류
등록 시 selector가 실패하면 즉시 전파하고 구독을 만들지 않습니다. 알림 중 selector, 비교 함수, 리스너의 오류는 모아서 처리합니다. 다른 활성 구독과 대기 중인 기록을 처리한 뒤 가장 바깥 알림 호출에서 원래 던진 값을 순서대로 담은 AggregateError를 던집니다. 대기열은 비워지며 다음 업데이트에서도 정상 동작합니다.
이미 저장된 상태는 되돌리지 않습니다. Selector나 비교 함수가 실패하면 이전 선택값 기준을 유지하며, 리스너의 실패는 기준을 갱신한 뒤 발생합니다. 알림 전달 밖에서 발생한 updater와 미들웨어 오류는 직접 전파됩니다.
명시적인 쓰기
set(value)는 함수도 값으로 해석하고 update(updater)는 계산으로 해석합니다. 둘 다 setState(valueOrUpdater)와 같은 미들웨어 경로를 사용합니다.