스토어 기반 구축하기
어댑터 및 라이브러리 작성자를 위한 가이드입니다.
@ilokesto/store는 상위 수준의 추상화를 위한 기반으로 사용되도록 설계되었습니다. 프레임워크 어댑터, 폼 라이브러리, 오버레이 컨트롤러, 그 밖의 상태 기반 패키지를 만드는 경우 이 페이지가 어떤 안정적인 계약 위에서 확장해야 하는지 설명합니다.
최소한의 계약 (The Minimal Contract)
Store<T> 클래스는 외부 도구가 상태와 상호작용하기 위해 필요한 최소한의 인터페이스를 제공합니다:
- 읽기를 위한
getState() - 쓰기를 위한
setState(next) - 변경 관찰을 위한
subscribe(listener)
상위 계층의 책임
Store 위에 무언가를 구축할 때는 코어 패키지가 의도적으로 맡지 않는 책임을 상위 계층이 가져가게 됩니다.
- 다른 런타임 모델로 상태를 매핑하기: 예를 들어 프레임워크의 반응성 시스템이나 도메인 전용 컨트롤러로 연결합니다.
- 생명주기 정리 책임지기: 소비자가 사라질 때 리스너를 해제합니다.
- 상위 수준의 사용성 추가하기: selector, action, reducer, validation, persistence, tooling 등을 얹습니다.
어댑터 생명주기
대부분의 어댑터는 비슷한 흐름을 따릅니다.
getState()로 현재 스냅샷을 읽습니다.subscribe(listener)로 이후 변경을 구독합니다.setState(next)또는 래핑된 액션을 통해 쓰기를 전달합니다.- 소비자가 사라질 때 구독을 정리합니다.
공개 계약의 경계 (Public Contract Boundaries)
Store를 기반으로 상위 수준의 라이브러리를 노출할 때, 다음 중 하나를 결정해야 합니다:
- Store 인스턴스 직접 노출: 바닐라 API를 사용하려는 고급 사용자에게 유용합니다.
- Store 래핑: 더 제한적이거나 전문화된 API를 제공합니다 (예:
setState를 숨기고 특정 액션만 노출).
안정적인 경계부터 사용하기
우선은 getState(), setState(next), subscribe(listener)라는 안정적인 표면 위에서 확장하는 편이 좋습니다.
더 깊은 구현 세부 사항에 의존해야 한다면, 장기적인 호환성 보장이 아니라 선택적 내부 동작에 기대고 있다는 점을 분명히 해야 합니다.
과도한 결합 방지
- 내부 필드에 의존하지 마십시오: 오직 공개된 메서드만 사용하십시오.
- 제네릭하게 유지하십시오: 라이브러리의 목적에 꼭 필요한 경우가 아니라면 상태 형태를 제한하지 않도록 노력하십시오.
- 다중 인스턴스 지원: 한 애플리케이션에 여러 스토어가 존재할 때도 라이브러리가 올바르게 작동하는지 확인하십시오.