호환성 표의 단위
함수마다 웹·Android·iOS의 존재 여부, 입력과 반환값, 오류, 취소, 권한, 백그라운드 동작을 기록합니다. fetch()처럼 같은 이름을 쓸 때에는 차이를 문서화하고, 동작이 크게 다르면 플랫폼 API로 분리합니다.
스피논 / JavaScript API 대응 명세
V8이 JavaScript 언어를 실행하는 것과 브라우저 API가 존재하는 것은 별개입니다. 스피논이 직접 제공할 함수, 모바일에서 달라지는 동작, 모바일 전용 함수와 초기 제외 항목을 분리합니다.
@spinon/platform의 명시적 API로 제공합니다. 실제 조사·구현 진행은 공식 JS API 구현 체크리스트에서 관리합니다.앱에 포함한 V8 버전과 빌드 옵션을 고정한 뒤 확인합니다. 언어 기능의 존재만으로 타이머·네트워크·DOM이 생기지는 않습니다.
| API·문법·객체 | 웹과의 관계 | 스피논 계약 | 상태 |
|---|---|---|---|
Promise Map Set | ECMAScript 언어 객체 | 선택한 V8 빌드에서 제공. 비동기 작업을 돌릴 마이크로태스크 체크포인트는 스피논 호스트가 정합니다. | 엔진 검증 |
JSON ArrayBuffer TypedArray | 언어 수준 데이터 기능 | JS 객체와 Rust·C++ 경계를 넘을 때 복사·소유권·크기 제한은 별도 계약으로 둡니다. | 엔진 검증 |
Intl Date | 언어 기능이지만 로케일·시간대 데이터에 영향 | V8/ICU 빌드, OS 시간대와 언어 데이터를 고정해 실제 결과를 비교합니다. | 조건 검증 |
globalThis | ECMAScript 전역 객체 참조 | 전역 객체 자체는 언어 기능입니다. 여기에 어떤 웹식 API를 설치할지는 스피논 호스트 계약으로 구분합니다. | 엔진 검증 |
웹과 같은 이름을 목표로 하지만 구현은 스피논 호스트에 둡니다. 첫 수직 구현에 필요한 최소 기능부터 제공합니다.
| API·문법·객체 | 웹에서의 용도 | 스피논 구현·검증 조건 | 첫 목표 |
|---|---|---|---|
setTimeout clearTimeout | 지연 작업·취소 | 호스트 스케줄러와 JS 이벤트 루프에 연결. 취소 후 콜백 수명과 앱 중단 시 동작을 검증합니다. | 수직 구현 |
queueMicrotask | 현재 작업 뒤의 미세 작업 | V8 마이크로태스크 큐와 호스트 콜백 경계의 실행 순서를 고정합니다. | 수직 구현 |
URL URLSearchParams | 주소 파싱·조합 | 표준 형태를 목표로 하며 상대 URL의 기준 주소를 모바일 앱에서 명시합니다. | 도구 확장 |
TextEncoder TextDecoder | 문자열·바이트 변환 | 지원 인코딩·오류 동작을 웹과 비교해 호스트 또는 폴리필로 제공합니다. | 도구 확장 |
AbortController | 비동기 작업 취소 신호 | fetch와 다른 호스트 호출이 취소를 어느 시점에 반영하는지 명시합니다. | 도구 확장 |
console | 로그·오류 조사 | 출력 대상, 오류 스택, 릴리스 로그 정책은 호스트가 정합니다. | 수직 구현 |
Blob File FormData | 바이너리 데이터·업로드 | 메모리 한도, 파일 핸들 수명, fetch 본문·스트림 연동을 정한 뒤 제공하며 초기 존재를 가정하지 않습니다. | 후속 단계 |
crypto.getRandomValues() crypto.randomUUID() | 안전한 난수·식별자 | OS 난수원을 연결하고 실패 및 백그라운드 동작을 검증합니다. V8 언어 엔진만으로 자동 제공되지 않습니다. | 도구 확장 |
모바일의 주 화면은 Rust가 소유하는 UI 트리를 GPU로 그립니다. 일부 DOM 호출 형태를 그 트리에 연결하는 제안이며, 브라우저 DOM 전체나 react-dom 호환을 뜻하지 않습니다. 후보 API와 미정 계약은 공식 DOM 호환 명세를 기준으로 합니다.
| API·문법·객체 | 웹에서의 용도 | 스피논 구현·검증 조건 | 상태 |
|---|---|---|---|
document.createElement() document.createTextNode()appendChild() insertBefore() removeChild() | 노드를 만들고 트리에 삽입·이동·제거 | 지원 노드 종류, 태그 이름 대소문자·잘못된 이름 예외, 문서 소속, 기존 부모에서 이동, insertBefore(node, null), 삽입·제거 반환값을 정합니다. 순환·잘못된 참조는 동기 DOMException으로 알리고 실패 시 트리를 보존해야 합니다. 노드 ID·JS wrapper 수명, 앱 루트와 GPU 연결, 프레임워크가 소유한 하위 트리에 직접 DOM 쓰기를 허용할지는 미정입니다. | 제안 · 계약 미정 |
nodeType nodeNameparentNode firstChild nextSiblingtextContent Text.data nodeValue | 노드 종류·관계·텍스트 조회와 변경 | textContent·Text.data의 getter/setter, 노드 종류별 nodeValue, 노드 이름·종류 상수, 분리된 노드의 수명을 정합니다. 동기 변경 직후 JS는 최신 논리 트리를 읽고 렌더러는 일관된 커밋 revision만 읽어야 합니다. | 제안 · 계약 미정 |
getAttribute() setAttribute() removeAttribute()id className | 기본 속성 읽기·쓰기 | 인수 변환, 속성 이름 대소문자, id/className과 id/class 속성의 반영 관계를 정합니다. 값 변경에 따른 선택자 재평가도 계약 대상입니다. style 속성과 CSSOM은 별도 계약 전까지 지원으로 간주하지 않습니다. | 제안 · 계약 미정 |
childNodes childrenNodeList HTMLCollection classList | 자식 컬렉션과 클래스 토큰 조작 | 라이브·정적 여부, 인덱스·반복 규칙, 클래스 토큰 검증과 toggle()의 인수·반환값이 정해지기 전까지 자동 포함하지 않습니다. | 별도 계약 |
document.body document.documentElementgetElementById() querySelector(All) | 문서 루트와 노드 검색 | 브라우저 페이지 루트를 그대로 제공하지 않습니다. 앱 표시 루트, 선택자 문법·검색 범위·결과 컬렉션을 별도로 정하기 전까지 첫 단계에서 제외하는 제안입니다. | 첫 단계 제외 제안 |
addEventListener() removeEventListener()dispatchEvent() Event | DOM 이벤트 등록·제거·전파·취소 | 이벤트 대상·revision, 전파·캡처 순서, stopPropagation()·preventDefault(), 포인터 취소와 키보드·접근성 활성화를 정해야 합니다. 노드 제거 또는 오래된 이벤트가 도착할 때 콜백을 해제·폐기하는 시점도 미정입니다. | 별도 계약 |
getBoundingClientRect() getComputedStyle() | 레이아웃·계산 스타일 조회 | 레이아웃 동기화, 캐시된 값, 읽기 비용과 반환값의 유효 시점을 정하기 전까지 미정입니다. | 미정 |
ShadowRoot customElements MutationObserverRange Selection iframe | 브라우저 문서·커스텀 요소·관찰·선택·중첩 문맥 | DOM façade의 기본 범위로 약속하지 않습니다. 각 기능의 별도 제품 범위와 동작 계약이 생기기 전까지 지원을 주장하지 않습니다. | 범위 외 제안 |
innerHTML outerHTML DOMParser | HTML 문자열 파싱·직렬화 | HTML 파서와 입력 보안 계약이 없으므로 첫 단계에서 제외하는 제안입니다. | 첫 단계 제외 제안 |
같은 소스가 컴파일되어도 브라우저의 출처·문서·탭 수명주기와 모바일 앱의 권한·백그라운드 규칙은 다릅니다.
| API·문법·객체 | 차이의 원인 | 스피논에서 정할 계약 | 첫 목표 |
|---|---|---|---|
fetch()Request Response HeadersAbortSignal | 브라우저 출처·CORS·쿠키·캐시와 앱 네트워크 권한·수명주기가 다릅니다. | V8만으로 제공되지 않는 호스트 API 제안입니다. 상대 URL 기준, Request 생성·검증, RequestInit의 최소 필드(method·headers·body·credentials·redirect 등), 요청 본문 형식, Headers 조회·수정·반복, Response.status/ok·헤더·본문 읽기 메서드(예: text()·json()·arrayBuffer()·blob()·formData())와 ReadableStream 여부는 모두 범위 미정입니다. 버전 있는 NetworkHost에서 캐시·리다이렉트·쿠키·TLS·취소·CORS/출처·앱 백그라운드 동작을 정합니다. HTTP 비성공 응답은 Response로, 전송 실패·취소는 별도로 처리합니다. 비동기 결과는 Isolate 소유 실행 경로에 보내고 V8 마이크로태스크 규칙을 따릅니다. 네트워크 스레드는 V8을 직접 만지지 않으며, Isolate 종료·앱 재시작·OTA 교체 시 취소·결과 폐기/거부·콜백 해제와 UI 비차단을 검증해야 합니다. 자세한 경계는 Fetch 호스트 명세를 따릅니다. | 제안 · 범위 미정 |
정적 importimport() import.meta | 웹 브라우저는 URL 모듈 그래프를 읽습니다. 모바일 첫 수직 구현은 정적 모듈을 단일 번들로 묶고, 이후 청크 그래프로 확장하는 계획입니다. | 정적 import는 첫 단일 번들에서 번들러가 해결합니다. 청크 그래프의 ESM 로딩과 동적 import(), import.meta 값은 별도 런타임 관문입니다. 활성 매니페스트 밖의 청크를 거부하고 누락·호환 버전 오류를 정의해야 하며 현재 지원으로 간주하지 않습니다. OTA 스냅샷은 앱 재시작에서 바꾸며 실행 중 모듈 교체를 뜻하지 않습니다. HMR·Fast Refresh는 개발 도구 계약으로 분리합니다. 자세한 내용은 실행·빌드·배포 명세를 따릅니다. | 런타임 계약 미정 |
WebSocket EventSource | 연결 유지·재연결이 앱 백그라운드 정책과 충돌할 수 있습니다. | 첫 목표 범위에는 포함하지 않습니다. 연결 상태, 인증, 중단·재개, 배터리 비용을 별도 명세한 뒤 판정합니다. | 첫 단계 제외 제안 |
requestAnimationFrame() cancelAnimationFrame() | 브라우저 문서 프레임 대신 모바일 GPU 표면의 프레임을 사용합니다. | 표시 주기, 콜백 시각, 취소 시점, 화면이 가려지거나 앱이 백그라운드일 때의 중단 규칙을 정합니다. | 렌더러 |
setInterval() clearInterval() | 앱 수명주기와 절전 정책에 따라 정지·지연될 수 있습니다. | 백그라운드에서 실행을 보장하지 않으며 취소와 재개 시 누락된 틱 처리를 정의합니다. | 도구 확장 |
performance.now() | 브라우저의 시간 원점과 앱 프로세스 수명이 다릅니다. | 단조 시계의 원점·정밀도·앱 재개 후 연속성을 기록합니다. 벤치마크에는 플랫폼 계측도 함께 씁니다. | 계측 |
스토리지 APIlocalStorage sessionStorage | 브라우저 출처·탭 단위 저장과 앱 설치·사용자 데이터 수명이 다릅니다. | 동기 브라우저 저장소 전역을 그대로 복제하지 않고 비동기 저장소 계약, 범위, 용량, 암호화와 삭제 정책을 설계합니다. | 도구 확장 |
아래 이름은 @spinon/platform의 API 형태 제안입니다. 웹 빌드에서는 지원 여부를 확인하는 대체 구현 또는 명시적 실패를 제공합니다. 실제 서명은 구현 전에 확정합니다.
| 제안 함수 | 필요한 이유 | 계약에 포함할 조건 | 첫 목표 |
|---|---|---|---|
getSafeAreaInsets() | 노치·상태 막대·제스처 영역 | 화면 회전과 창 크기 변경 시 값 갱신, CSS 안전 영역과의 관계 | 실사용 UI |
onAppStateChange() | 전경·백그라운드·복귀 처리 | 구독 해제, 이벤트 순서, 일시 중단된 JS 작업의 재개 | 수직 구현+ |
onBackPress() | Android 시스템 뒤로 가기 | 라우터에 이전 방문 항목이 있는지 먼저 확인하고, 루트 화면의 동작은 플랫폼 정책으로 명시합니다. iOS·웹은 각각의 뒤로 가기 입력에 연결합니다. | 실사용 UI |
dismissKeyboard() | 모바일 소프트 키보드 제어 | IME 조합 중 취소·확정, 포커스 이동과 이벤트 순서 | 실사용 UI |
requestPermission() | 카메라·사진·위치 등 OS 권한 | 권한 종류, 거절·재요청·설정 이동, 플랫폼별 상태 차이 | 플랫폼 기능 |
hapticFeedback() | 진동·촉각 반응 | 기기 지원 여부와 강도 차이, 무음/절전 상태 | 플랫폼 기능 |
openExternalURL() | 앱 밖의 링크·딥링크 열기 | 허용 스킴, 실패 결과, 앱 복귀와 보안 정책 | 실사용 UI |
함수마다 웹·Android·iOS의 존재 여부, 입력과 반환값, 오류, 취소, 권한, 백그라운드 동작을 기록합니다. fetch()처럼 같은 이름을 쓸 때에는 차이를 문서화하고, 동작이 크게 다르면 플랫폼 API로 분리합니다.
V8을 연결하는 엔진 내부 어댑터는 필요하지만 React Native의 JSI를 가져오거나 V8 핸들을 앱 API로 공개할 필요는 없습니다. 앱에서 자체 Kotlin·Swift·Rust·C++ 기능을 JS로 쓰게 하려면 별도의 버전 있는 플랫폼 모듈 계약이 필요합니다. JS 타입 선언, 빌드 시 연결, 플랫폼 구현 등록, 비동기 오류·취소, 권한, 스레드와 객체 수명을 계약하고 일반 데이터 전달과 고용량 zero-copy 자원 경로를 분리합니다. 이 기능은 아직 지원되지 않으며 J15 사용자 정의 네이티브 모듈 작업에서 추적합니다.
기존 V8 동적 트리 PoC는 JS 호출과 이벤트 연결을 확인한 자료입니다. 이 문서의 제한 DOM façade, fetch(), 타이머, 저장소, 모바일 전용 함수가 실제 앱에서 동작한다는 증거는 아닙니다. 먼저 작은 카운터 앱에 필요한 타이머·마이크로태스크 계약을 구현합니다. 기준 자료: V8 임베딩 문서, DOM 표준, Fetch 표준.