npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

boot-welcome-usb

v0.1.0

Published

EventBoot Welcome AOA Module

Readme

boot-welcome-usb

Android AOA(Android Open Accessory) 프로토콜을 통해 USB로 연결된 Mac/PC와 통신하는 Expo Native Module.

개요

WelcomeUSBFront 기능에서 사용되며, Android 태블릿(Accessory)이 Mac의 EventBoot-Desktop(Host)과 USB 케이블을 통해 QR 코드 접수 데이터를 주고받습니다.

Android 태블릿 (이 모듈)  ──USB 케이블──  Mac (eventboot-desktop)
      Accessory 모드                        Host 모드

프로젝트 구조

boot-welcome-usb/
├── android/
│   ├── build.gradle
│   └── src/main/java/net/eventboot/welcomeusb/
│       ├── BootWelcomeUsbModule.kt      # Expo Module 정의
│       ├── AoaAccessoryManager.kt       # USB Accessory 연결 관리
│       └── AoaProtocol.kt              # 메시지 프레이밍
├── src/
│   ├── index.ts                         # 모듈 export
│   ├── BootWelcomeUsb.types.ts         # TypeScript 타입
│   ├── BootWelcomeUsbModule.ts         # 네이티브 모듈 바인딩
│   └── useUsbAoa.ts                    # React Hook
├── example/                            # 테스트용 예제 앱
├── build/                              # TypeScript 빌드 산출물
├── expo-module.config.json
└── package.json

개발 환경 설정

모듈 빌드

cd modules/boot-welcome-usb

# TypeScript 빌드
npm run build

# 빌드 산출물 삭제
npm run clean

# 린트
npm run lint

example 앱 실행

cd modules/boot-welcome-usb/example

npm install
npx expo run:android

example 앱은 package.jsonexpo.autolinking.nativeModulesDir 설정으로 상위 모듈을 자동 인식합니다.

eventboot 프로젝트에서 사용하기

1. 의존성 등록

package.json (프로젝트 루트)에 로컬 경로로 추가:

{
  "dependencies": {
    "boot-welcome-usb": "./modules/boot-welcome-usb"
  }
}
npm install

2. Config Plugin 등록

app.jsonplugins 배열에 AOA Config Plugin이 등록되어 있어야 합니다:

{
  "plugins": [
    "./plugins/withAndroidAoaAccessory"
  ]
}

이 플러그인은 Android Manifest에 USB Accessory 관련 설정을 자동으로 추가합니다.

3. 네이티브 빌드

Expo Native Module이므로 네이티브 빌드가 필요합니다. Expo Go에서는 동작하지 않습니다.

# 개발 빌드
eas build --profile development --platform android

# 또는 로컬 빌드
npx expo run:android

API 사용법

기본 함수

import BootWelcomeUsbModule, {
  getConnectionState,
  requestPermission,
  sendData,
  addListener,
} from 'boot-welcome-usb';

// 연결 상태 확인
const state = await getConnectionState();
// 'DISCONNECTED' | 'CONNECTED' | 'AOA_SWITCHING' | 'AOA_READY' | 'ERROR'

// USB 권한 요청
const granted = await requestPermission();

// 데이터 전송 (JSON 문자열)
const success = await sendData(JSON.stringify({
  id: 'uuid-123',
  type: 'REQUEST',
  path: '/scan',
  body: JSON.stringify({ qrcode: 'TICKET-001' }),
}));

이벤트 리스너

import { addListener } from 'boot-welcome-usb';

// 연결 상태 변경
const sub1 = addListener('onConnectionStateChanged', (event) => {
  console.log('상태:', event.state, event.message);
});

// 데이터 수신 (Host로부터 응답)
const sub2 = addListener('onDataReceived', (event) => {
  const message = JSON.parse(event.messageJson);
  console.log('수신:', message);
});

// 에러
const sub3 = addListener('onError', (event) => {
  console.error('에러:', event.code, event.message);
});

// 정리
sub1.remove();
sub2.remove();
sub3.remove();

React Hook

import { useUsbAoa } from 'boot-welcome-usb';

function MyComponent() {
  const { connectionState, isConnected } = useUsbAoa();

  return <Text>{isConnected ? '연결됨' : '미연결'}</Text>;
}

useWelcomeUSBFront Hook (앱 내부)

실제 WelcomeUSBFront 화면에서는 이 훅을 사용합니다. 기존 HTTP 방식과 동일한 WelcomeDeskApiResult를 반환합니다:

import { useWelcomeUSBFront } from '@/hooks/welcome/useWelcomeUSBFront';

function WelcomeUSBScreen() {
  const { connectionState, isConnected, sendQRCode, requestPermission } = useWelcomeUSBFront();

  const handleScan = async (qrcode: string) => {
    const result = await sendQRCode(qrcode);
    // result: { customer, receptionResult, isError, errorMessage }
  };
}

통신 프로토콜

메시지 프레이밍

USB 스트림은 메시지 경계가 없으므로 Length-Prefix 프레이밍을 사용합니다:

+-------------------+------------------------+
| Length (4 bytes)  | JSON Payload (N bytes) |
| Big-Endian uint32 | UTF-8 encoded          |
+-------------------+------------------------+

메시지 형식

interface AoaMessage {
  id: string;      // UUID (요청-응답 매칭)
  type: 'REQUEST' | 'RESPONSE' | 'PING' | 'PONG';
  path: string;    // "/scan", "/ping"
  body?: string;   // JSON 문자열
}

요청/응답 예시

QR 스캔 요청 (Android → Mac):

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "type": "REQUEST",
  "path": "/scan",
  "body": "{\"qrcode\":\"TICKET-12345\"}"
}

QR 스캔 응답 (Mac → Android):

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "type": "RESPONSE",
  "path": "/scan",
  "body": "{\"data\":{\"customer\":{\"name\":\"홍길동\"},\"receptionResult\":\"OK_IN\"}}"
}

테스트 환경

  • Android 에뮬레이터: USB Accessory 테스트 불가. 실기기 필수.
  • ADB 충돌: AOA 모드 전환 시 ADB 연결이 끊어질 수 있음. adb kill-server 후 테스트 권장.
  • Mac에서 EventBoot-Desktop 실행 필수: USB Host 역할을 하는 modules/eventboot-desktop Electron 앱이 Mac에서 실행 중이어야 함.