@cp949/rx-registry
v1.0.0
Published
RxJS-backed observable registry with ordered variant. Requires rxjs as peer dependency.
Maintainers
Readme
@cp949/rx-registry
RxJS 기반의 타입 안전 reactive key-value 저장소.
RxRegistry(비순서)와 RxSortableRegistry(삽입 순서 유지) 두 가지를 제공한다.
왜 bare BehaviorSubject 대신 쓰는가
bare BehaviorSubject<Map<string, Item>> 패턴의 불편함:
- 키 존재 여부를 매번
value.has(key)+distinctUntilChanged로 따로 구현해야 함 - 값 변경 시 새 Map 복사 +
next()호출을 반복해야 함 - 특정 키만 subscribe하거나 count 변화만 observe하려면 파생 observable을 직접 작성해야 함
rx-registry는 이 반복 패턴을 observeValue(key), observeKeyExists(key), observeCount() 등으로 미리 제공한다.
RxRegistry vs RxSortableRegistry
| | RxRegistry | RxSortableRegistry |
|---|---|---|
| 순서 | 삽입 순서 보장 (Map 기반) | 명시적으로 관리되는 순서 |
| 추가 API | - | append, prepend, insertAt, sort |
| 사용 시나리오 | 순서 무관한 lookup table | UI 리스트, drag-and-drop |
설치
pnpm add @cp949/rx-registry rxjsrxjs ^7 또는 ^8이 peer dependency다.
기본 사용
import { RxRegistry } from "@cp949/rx-registry";
interface User { id: string; name: string }
const users = new RxRegistry<string, User>();
// 구독 시작
const sub = users.observeValues().subscribe((list) => console.log(list));
// 데이터 추가
users.add("u1", { id: "u1", name: "Alice" });
users.add("u2", { id: "u2", name: "Bob" });
// 키 존재 여부 observe
users.observeKeyExists("u1").subscribe((exists) => console.log("u1 exists:", exists));
// 특정 키 값 observe
users.observeValue("u1").subscribe((user) => console.log("u1:", user));
sub.unsubscribe();RxSortableRegistry 사용
import { RxSortableRegistry } from "@cp949/rx-registry";
const items = new RxSortableRegistry<string, { label: string }>();
items.add("a", { label: "A" });
items.add("b", { label: "B" });
items.prepend("b", { label: "B-top" }); // b를 맨 앞으로
console.log(items.keys()); // ["b", "a"]생성 경로
// 배열로 생성
const reg = RxRegistry.fromValues(["x", "y", "z"]);
// keyFn 지정
const reg2 = RxRegistry.fromValues(items, { keyFn: (item) => item.id });Breaking Changes (0.x → 1.0.0)
records()삭제: 내부 상태를 plain object로 노출하던 메서드.entries()로 대체.replaceAllRecords()삭제:replaceAll(data, keyFn)으로 대체.- object observable API 삭제: plain object 기반 관찰 경계를 제거.
observeKeys(),observeValue(),observeValues()조합으로 대체. - object factory 삭제: 생성 경로를
fromValues()로 통일.
주의사항
observeValues()가 반환하는 배열은 안전하게 mutate 가능 (snapshot copy).observeSharedValues()가 반환하는 배열은 구독자 간 공유됨 — mutate 금지.keys(),entries()결과는 snapshot — 안전하게 mutate 가능.- key 타입에 별도 제약이 없다. string·number가 일반적이지만 object, symbol도 사용 가능 (
Mapsemantics). RxSortableRegistry의 key 탐색과 제거는Map과 동일한 SameValueZero 기준을 따른다 (NaN등 포함).
설계 결정
rx-registry는 @cp949/registry에 의존하지 않으며 유틸 타입을 자체 포함한다. 의존성 그래프를 단순하게 유지하기 위한 의도적 결정이다.
key equality는 내부 Map의 SameValueZero semantics를 따른다. RxSortableRegistry는 key 순서 배열을 별도로 유지하며, 이 배열에서의 탐색·제거도 동일한 SameValueZero 기준으로 동작한다 (NaN key 재배치·삭제 포함).
