Product case study
스마트펜 Web SDK
TypeScript와 Web Bluetooth로 브라우저에서 스마트펜을 연결하고 필기 데이터를 받는 공개 SDK와 샘플 앱입니다.

01
여러 펜의 연결 상태와 이벤트 처리
Context
같은 펜에 연결 요청이 겹치거나 Bluetooth 서비스가 중복으로 등록되면, 여러 펜을 쓸 때 연결 상태와 입력 이벤트가 서로 섞일 수 있었습니다.
Goal
펜마다 연결 상태와 이벤트를 따로 관리하고, 같은 장치에 중복으로 연결되는 일을 막아야 했습니다.
What I changed
- 이미 연결 중이거나 연결된 장치에는 요청이 다시 실행되지 않게 하고, Bluetooth 서비스가 한 번만 등록되도록 수정했습니다.
- 장치 식별자로 펜을 찾는 API와 펜별 연결 상태를 조회하는 기능을 추가했습니다.
- 입력과 상태 이벤트가 해당 펜 인스턴스로 전달되도록 콜백 처리를 정리했습니다.
Outcome
여러 펜을 연결해도 각 펜의 연결 상태와 입력이 정확히 구분되어 조회되고 처리됩니다.
02
오프라인 스트로크와 펌웨어 호환성
Context
오프라인 스트로크를 모두 받기 전에 수신이 끝난 것으로 처리되는 경우가 있었고, 펌웨어 프로토콜 버전에 따라 압축 방식과 패킷 처리도 달랐습니다.
Goal
오프라인 스트로크의 순서와 완료 시점을 정확히 잡고, 압축 지원 여부가 다른 펜에서도 펌웨어 전송이 동작해야 했습니다.
What I changed
- 샘플 앱에서 오프라인 스트로크를 페이지별로 나누어 그리고, 모든 데이터를 받은 뒤에 완료 처리하도록 수정했습니다.
- 패킷 조각의 이스케이프 처리와 펜 입력 필드를 정리했습니다.
- 프로토콜 버전에 따라 펌웨어 압축 지원 여부를 확인하고, 지원하지 않는 펜에는 압축하지 않은 데이터를 보냈습니다.
Outcome
오프라인 스트로크가 일부 빠지거나 잘못 그려지는 문제가 사라졌고, 압축 지원 여부가 다른 펜에서도 펌웨어를 전송할 수 있습니다.
03
공개 API와 개발 자료 정리
Context
일부 타입은 SDK 내부 경로에서 직접 불러와야 했고, 콜백 타입과 문서가 실제 API 사용 방식과 맞지 않는 부분이 있었습니다. 브라우저 빌드도 Node.js 의존성 때문에 실패할 수 있었습니다.
Goal
패키지의 공개 경로에서 필요한 타입과 API를 쓸 수 있게 하고, SDK와 샘플을 현재 브라우저 빌드 환경에 맞추는 것이 목표였습니다.
What I changed
- 펜 입력 타입과 콜백 타입을 정리해 패키지의 루트 경로에서 내보냈습니다.
- 브라우저 빌드를 막던 압축 라이브러리 의존성을 제거하고 Webpack 설정과 관련 패키지를 정리했습니다.
- 샘플 앱의 내부 경로 의존성을 없애고 빠른 시작, API 사용법, 입력 데이터 필드 문서를 보완했습니다.
Outcome
SDK 사용자는 내부 파일 경로를 몰라도 공개 타입과 API만으로 개발할 수 있고, 샘플 코드와 문서도 공개 API 기준으로 맞춰졌습니다.