# @coxwave/tap-sdk

간단한 JavaScript API로 웹 애플리케이션에 EduTap AI 튜터를 임베드할 수 있습니다.

## 설치

```bash
npm install @coxwave/tap-sdk
# 또는
pnpm add @coxwave/tap-sdk
# 또는
yarn add @coxwave/tap-sdk
```

## 빠른 시작

```typescript
import TapSDK from "@coxwave/tap-sdk";

// 1단계: API 키로 SDK 인스턴스 생성
const sdk = new TapSDK({ apiKey: "your-api-key" });

// 2단계: 설정값과 함께 초기화
await sdk.init({
  buttonId: "tap-button", // 토글 버튼을 부착할 HTML 요소의 ID
  course: {
    userId: "user-123",
    courseId: "course-456",
    clipId: "clip-789",
  },
  container: {
    position: { top: "64px", right: "32px" },
    width: "360px",
    height: "calc(100% - 128px)",
    borderRadius: "18px",
  },
});

// 3단계: 채팅 상태 확인 (선택사항)
console.log("채팅 열림 상태:", sdk.isOpen);
```

## 커스터마이징

### 토글 버튼

SDK는 제공된 `buttonId`를 가진 요소에 알람 뱃지와 클릭 핸들러를 자동으로 부착합니다.

### 채팅 컨테이너

채팅 화면은 고정 위치 컨테이너입니다. `container` 옵션으로 커스터마이징할 수 있습니다:

- `position` — `{ top/right/bottom/left }` 값 (단위가 포함된 문자열)
- `width` / `height` — CSS 단위를 포함한 문자열
- `borderRadius` — 테두리 반경 (예: "16px")

컨테이너는 채팅이 열리고 닫힐 때 자동으로 표시/숨김되며, EduTap이 PDF를 표시할 때 확장됩니다.

### 알람 알림 및 팝업

EduTap은 iframe 채널을 통해 풍부한 알람 알림과 HTML 팝업을 전송할 수 있습니다. SDK는 자동으로 알람을 페이드 인/아웃하고, 클릭을 처리하며, 채팅 컨테이너 옆에 팝업을 렌더링합니다.

## API Reference

### 생성자

```typescript
new TapSDK(config: TapKitConfig)
```

SDK 인스턴스를 생성합니다.

**매개변수:**
- `config.apiKey` (필수) – EduTap API 키

### `init(params)`

iframe을 초기화하고, 핸드셰이크를 수행하며, UI 컨트롤을 연결합니다.

```typescript
await sdk.init({
  buttonId: "tap-button",
  course: {
    userId: "user-123",
    courseId: "course-456",
    clipId: "clip-789",
  },
  container: {
    position: { top: "64px", right: "32px" },
    width: "360px",
    height: "calc(100% - 128px)",
  },
});
```

**매개변수:**
- `buttonId` (필수) – 토글 버튼을 부착할 HTML 요소의 ID
- `course` (필수) – `userId`, `courseId`, `clipId`를 포함한 강의 컨텍스트
- `container?` (선택) – `position`, `width`, `height`, `borderRadius`를 포함한 UI 커스터마이징

**반환값:** `Promise<void>`

### `ready`

SDK가 완전히 로드되고 사용 가능한 상태가 되면 resolve되는 Promise입니다.

```typescript
await sdk.ready;
console.log("SDK 사용 준비 완료");
```

### `events.seekTimeline(params)`

VOD 통합을 위해 타임라인 업데이트를 EduTap으로 전송하여 호스트 플레이어와 동기화합니다.

```typescript
await sdk.events.seekTimeline({
  clipId: "clip-42",
  clipPlayHead: 132.4
});
```

**매개변수:**
- `clipId` (필수) – 현재 재생 중인 클립 ID
- `clipPlayHead` (필수) – 현재 재생 위치 (초 단위)

**반환값:** `Promise<void>`

### `destroy()`

모든 리스너를 해제하고, iframe 및 토글 버튼을 제거하며, 내부 상태를 초기화합니다.
단일 페이지 애플리케이션에서 컴포넌트 언마운트 시 호출하세요.

```typescript
sdk.destroy();
```

## 이벤트 시스템

이벤트는 `sdk.events`를 통해 제공됩니다. 모든 리스너는 구독 해제 함수를 반환합니다.

### `events.onAlarmFadeIn(handler)`

알람 메시지가 표시될 때 호출됩니다.

```typescript
sdk.events.onAlarmFadeIn((messageInfo) => {
  console.log("새 알람:", messageInfo.messageContent);
  console.log("메시지 ID:", messageInfo.messageId);
});
```

**매개변수:**
- `messageInfo.messageId` – 메시지 ID
- `messageInfo.messageContent` – 메시지 내용
- `messageInfo.timestamp` – 타임스탬프

### `events.onTimelineSeek(handler)`

EduTap에서 타임라인 시크를 요청할 때 호출됩니다.

```typescript
sdk.events.onTimelineSeek((clipPlayHead, clipId) => {
  console.log(`클립 ${clipId}의 ${clipPlayHead}초로 이동 요청`);
  // 비디오 플레이어를 해당 위치로 이동
  videoPlayer.seekTo(clipPlayHead);
});
```

**매개변수:**
- `clipPlayHead` (number) – 재생 위치 (초)
- `clipId` (string) – 클립 ID

## TypeScript 지원

타입 정의가 패키지에 포함되어 있습니다. 주요 export:

```ts
import type {
  TapKitConfig,
  TapKitInitParams,
  Course,
  ContainerStyle,
  PositionType,
  SeekTimelineParamsType,
  AlarmMessageInstanceType,
} from "@coxwave/tap-sdk";
```

## 보안 고려사항

사이트에서 Content Security Policy (CSP) 헤더를 사용하는 경우, 다음 지시문을 추가하세요:

```http
Content-Security-Policy:
  script-src 'self' https://files.edutap.ai;
  style-src 'self' 'unsafe-inline';
  connect-src 'self' https://your-tap-api-domain.com;
  frame-src 'self' https://your-edutap-domain.com;
```

## 브라우저 지원

- Chrome 60+
- Firefox 60+
- Safari 12+
- Edge 79+

## 라이선스

MIT © 2025 Coxwave

## 속성

### `isOpen`

채팅 인터페이스가 현재 열려 있으면 `true`를 반환합니다.

```ts
if (sdk.isOpen) {
  console.log("채팅이 현재 열려 있습니다");
}
```

### `isInitialized`

SDK가 성공적으로 초기화되면 `true`를 반환합니다.

```ts
if (sdk.isInitialized) {
  console.log("SDK 사용 준비 완료");
}
```
