0.1.0-draft

0002 · UI 트리와 이벤트

상태: 제안 · 명세 버전: 0.1.0-draft

호스트 작업

프레임워크 어댑터는 다음 의미의 작업을 스피논 호스트에 제출한다. 이 목록은 언어 간 C ABI 형식이 아니라 의미 계약이다.

작업입력과 효과실패 조건
create새 노드 ID, 태그 종류, 초기 속성으로 분리된 노드를 만든다.같은 수명의 중복 ID, 미지원 태그, 잘못된 속성
insert부모 ID와 삽입 위치를 지정해 노드를 트리에 연결한다.없는 부모, 순환 참조, 허용되지 않는 자식 종류
update속성 또는 텍스트 값을 바꾸고 필요한 스타일·배치·그리기 영역을 무효화한다.제거된 노드, 잘못된 값
move살아 있는 노드와 하위 트리를 새 위치로 옮긴다.순환 참조, 다른 트리 수명
remove노드와 하위 트리를 제거하고 연결된 이벤트·자원 참조를 해제 대상으로 표시한다.제거된 노드의 재사용
commit앞선 작업 묶음을 검증해 새 트리 revision으로 공개한다.묶음 내부의 참조·순서 오류

초기 Rust 코어는 0이 아닌 64비트 노드 ID를 받고, 성공한 생성·삭제 뒤 같은 트리 수명에서 ID를 재사용하지 않는다. 커밋은 기준 revision을 검사하고 작업 묶음 전체를 후보 상태에 적용한다. 어느 작업이 실패하면 기존 트리와 revision을 보존하고 묶음 전체를 거부한다. 이 초안의 오류에는 실패한 작업의 0 기반 위치가 포함되며 자동 재시도는 하지 않는다. 빈 묶음은 revision을 올리지 않는다. 세부 Rust API와 제한은 내부 트리 코어 명세를 따른다.

이 결정은 내부 Rust 코어의 실험 계약이다. spec/0002의 웹·모바일 공통 의미와 제안 상태를 확정하지 않으며 C ABI, JavaScript 어댑터의 재동기화·재시도, 이벤트 수명은 별도 작업으로 남는다. commit 성공은 트리 갱신을 뜻하며 픽셀 표시 완료를 뜻하지 않는다.

웹 DOM 이름과 호출 형태를 일부 제공하는 제안은 모바일 DOM 호환 명세를 따른다. 현재 S01 트리 모델은 요소 안의 선택적 텍스트와 노드 자식 목록으로 되어 있어, DOM의 요소·텍스트 노드가 순서대로 섞인 자식을 표현하지 못한다. DOM façade가 이 실험 구조를 곧바로 공개 API로 감싸서는 안 된다. 문서·노드 종류, 동기 조회·변경, wrapper 수명과 오류 의미를 포함한 별도 트리 계약이 필요하다.

프레임워크의 React Fiber, Vue 반응성, Svelte 컴파일 결과는 각 어댑터가 소유한다. Rust 코어는 이 알고리즘을 재구현하지 않고 호스트 작업과 그 결과만 소유한다.

이벤트

플랫폼 입력 → 좌표·대상 판정 또는 접근성 동작 → 노드 ID·이벤트 종류 → 등록된 JS 핸들러 순서로 전달한다. 이벤트는 해당 트리 revision과 연결돼야 한다. 제거된 노드의 콜백은 해제돼야 하며, 지연 중인 이벤트가 제거된 노드를 가리킬 때의 폐기·재대상 지정 규칙은 미정이다.

S05를 완료하기 전에는 오래된 revision의 이벤트를 받은 어댑터의 동작과 콜백 해제 시점을 확정한다. 이벤트 전파·기본 동작·동기 취소는 별도 범위로 남는다.

첫 수직 구현의 목표는 <button> 활성화와 클릭이다. onClick은 React 어댑터의 작성 문법이며 Vue·Svelte는 자체 문법을 사용한다. 이벤트 전파, 캡처, stopPropagation(), preventDefault(), 포인터 취소, 키보드 활성화 순서는 아직 확정하지 않았다. 해당 동작을 웹과 같다고 주장하기 전에 표준 이벤트 시나리오와 플랫폼 접근성 활성화 시나리오를 명세해야 한다.

스레드와 수명

JS Isolate·Rust 트리·GPU 표면은 각각 소유 경계가 있다. 핸들·콜백·GPU 자원을 다른 경계로 넘길 때 소유자, 해제 시점, 오류 전달을 정한다. OS 입력 스레드가 JS 완료를 기다려야 하는 동작과 비동기로 넘길 수 있는 동작은 미정이며 실기기 지연 측정과 함께 결정한다.