@coxwave/tap-sdk 0.2.1 → 0.2.2-demo.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -178
- package/dist/index.d.cts +26 -21
- package/dist/index.d.ts +26 -21
- package/dist/index.global.js +2 -2
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/index.ts +143 -79
- package/package.json +1 -1
- package/types.ts +4 -4
package/README.md
CHANGED
|
@@ -1,71 +1,32 @@
|
|
|
1
1
|
# @coxwave/tap-sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
간단한 JavaScript API로 웹 애플리케이션에 EduTap AI 튜터를 임베드할 수 있습니다.
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
This package is a **bootloader** that follows the ChannelTalk pattern:
|
|
8
|
-
|
|
9
|
-
1. **Loader Package** (`@coxwave/tap-sdk`) - Published to npm (~2.3KB)
|
|
10
|
-
- Provides the familiar `TapSDK` API
|
|
11
|
-
- Dynamically loads the actual SDK from CloudFront CDN
|
|
12
|
-
- Handles version management and integrity checks
|
|
13
|
-
- Only needs updates when API surface changes
|
|
14
|
-
|
|
15
|
-
2. **Core SDK** (`tap-kit-core`) - Deployed to S3/CloudFront
|
|
16
|
-
- Contains the actual implementation (UI, iframe management, etc.)
|
|
17
|
-
- Can be updated instantly without npm publishing
|
|
18
|
-
- Version controlled with timestamps (YYYYMMDDHHMMSS format)
|
|
19
|
-
- URL: `https://files.edutap.ai/tap-sdk/core-{VERSION}.js`
|
|
20
|
-
|
|
21
|
-
### Why This Architecture?
|
|
22
|
-
|
|
23
|
-
- **Instant Updates**: Deploy bug fixes and features to all users immediately
|
|
24
|
-
- **Smaller npm Package**: ~2-3KB loader vs ~20KB+ full SDK
|
|
25
|
-
- **Version Control**: Centralized version management via CDN
|
|
26
|
-
- **Integrity Checks**: Subresource Integrity (SRI) ensures security
|
|
27
|
-
- **Backward Compatibility**: Same API surface, seamless for existing users
|
|
28
|
-
|
|
29
|
-
## Installation
|
|
30
|
-
|
|
31
|
-
### via npm
|
|
5
|
+
## 설치
|
|
32
6
|
|
|
33
7
|
```bash
|
|
34
8
|
npm install @coxwave/tap-sdk
|
|
35
|
-
#
|
|
9
|
+
# 또는
|
|
36
10
|
pnpm add @coxwave/tap-sdk
|
|
37
|
-
#
|
|
11
|
+
# 또는
|
|
38
12
|
yarn add @coxwave/tap-sdk
|
|
39
13
|
```
|
|
40
14
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
When you install `@coxwave/tap-sdk` from npm, you get a small loader that:
|
|
44
|
-
|
|
45
|
-
1. Imports the package normally: `import TapSDK from '@coxwave/tap-sdk'`
|
|
46
|
-
2. On instantiation, loads the core SDK from `https://files.edutap.ai/tap-sdk/core-{VERSION}.js`
|
|
47
|
-
3. Proxies all API calls to the loaded core SDK
|
|
48
|
-
4. Verifies integrity using SHA-384 hashes
|
|
49
|
-
|
|
50
|
-
**No code changes required** - the API is identical to the previous monolithic SDK.
|
|
51
|
-
|
|
52
|
-
## Quick Start
|
|
53
|
-
|
|
54
|
-
### ES Modules (npm)
|
|
15
|
+
## 빠른 시작
|
|
55
16
|
|
|
56
17
|
```ts
|
|
57
18
|
import TapSDK from "@coxwave/tap-sdk";
|
|
58
19
|
|
|
59
20
|
const sdk = new TapSDK({
|
|
60
|
-
apiKey: "your-
|
|
21
|
+
apiKey: "your-api-key",
|
|
61
22
|
});
|
|
62
23
|
|
|
63
24
|
await sdk.init({
|
|
64
|
-
buttonId: "tap-button", //
|
|
25
|
+
buttonId: "tap-button", // 토글 버튼을 부착할 HTML 요소의 ID
|
|
65
26
|
course: {
|
|
66
27
|
userId: "user-123",
|
|
67
28
|
courseId: "course-456",
|
|
68
|
-
clipId:
|
|
29
|
+
clipId: "clip-789",
|
|
69
30
|
},
|
|
70
31
|
container: {
|
|
71
32
|
position: { top: "64px", right: "32px" },
|
|
@@ -76,66 +37,41 @@ await sdk.init({
|
|
|
76
37
|
});
|
|
77
38
|
```
|
|
78
39
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
```mermaid
|
|
82
|
-
sequenceDiagram
|
|
83
|
-
participant App as Your App
|
|
84
|
-
participant Loader as tap-sdk (npm)
|
|
85
|
-
participant CDN as CloudFront CDN
|
|
86
|
-
participant Core as Core SDK
|
|
87
|
-
|
|
88
|
-
App->>Loader: import TapSDK
|
|
89
|
-
App->>Loader: new TapSDK(config)
|
|
90
|
-
Loader->>CDN: GET /tap-sdk/core-{VERSION}.js
|
|
91
|
-
CDN-->>Loader: JavaScript Bundle
|
|
92
|
-
Loader->>Core: Initialize with config
|
|
93
|
-
App->>Loader: sdk.init(params)
|
|
94
|
-
Loader->>Core: Forward init call
|
|
95
|
-
Core-->>App: Chat Interface Ready
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
On initialization the SDK:
|
|
99
|
-
|
|
100
|
-
- ensures it is running in a browser (guards against SSR)
|
|
101
|
-
- injects the chat container into `document.body`
|
|
102
|
-
- renders the EduTap iframe and performs a handshake for authentication
|
|
103
|
-
- attaches to the element with the provided `buttonId`
|
|
104
|
-
|
|
105
|
-
## Customisation
|
|
40
|
+
## 커스터마이징
|
|
106
41
|
|
|
107
|
-
###
|
|
42
|
+
### 토글 버튼
|
|
108
43
|
|
|
109
|
-
|
|
44
|
+
SDK는 제공된 `buttonId`를 가진 요소에 알람 뱃지와 클릭 핸들러를 자동으로 부착합니다.
|
|
110
45
|
|
|
111
|
-
###
|
|
46
|
+
### 채팅 컨테이너
|
|
112
47
|
|
|
113
|
-
|
|
48
|
+
채팅 화면은 고정 위치 컨테이너입니다. `container` 옵션으로 커스터마이징할 수 있습니다:
|
|
114
49
|
|
|
115
|
-
- `position` —
|
|
116
|
-
- `width` / `height` —
|
|
117
|
-
- `borderRadius` —
|
|
50
|
+
- `position` — `{ top/right/bottom/left }` 값 (단위가 포함된 문자열)
|
|
51
|
+
- `width` / `height` — CSS 단위를 포함한 문자열
|
|
52
|
+
- `borderRadius` — 테두리 반경 (예: "16px")
|
|
118
53
|
|
|
119
|
-
|
|
54
|
+
컨테이너는 채팅이 열리고 닫힐 때 자동으로 표시/숨김되며, EduTap이 PDF를 표시할 때 확장됩니다.
|
|
120
55
|
|
|
121
|
-
###
|
|
56
|
+
### 알람 알림 및 팝업
|
|
122
57
|
|
|
123
|
-
EduTap
|
|
58
|
+
EduTap은 iframe 채널을 통해 풍부한 알람 알림과 HTML 팝업을 전송할 수 있습니다. SDK는 자동으로 알람을 페이드 인/아웃하고, 클릭을 처리하며, 채팅 컨테이너 옆에 팝업을 렌더링합니다.
|
|
124
59
|
|
|
125
60
|
## Runtime API
|
|
126
61
|
|
|
127
62
|
### `init(options)`
|
|
128
63
|
|
|
129
|
-
|
|
64
|
+
iframe을 초기화하고, 핸드셰이크를 수행하며, UI 컨트롤을 연결합니다.
|
|
130
65
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
- `
|
|
134
|
-
- `
|
|
66
|
+
**옵션:**
|
|
67
|
+
|
|
68
|
+
- `buttonId` (필수) – 토글 버튼을 부착할 HTML 요소의 ID
|
|
69
|
+
- `course` (필수) – `userId`, `courseId`, `clipId`를 포함한 강의 컨텍스트
|
|
70
|
+
- `container?` – `position`, `width`, `height`, `borderRadius`를 포함한 선택적 UI 커스터마이징
|
|
135
71
|
|
|
136
72
|
### `events.seekTimeline({ clipId, clipPlayHead })`
|
|
137
73
|
|
|
138
|
-
|
|
74
|
+
VOD 통합을 위해 타임라인 업데이트를 EduTap으로 전송하여 호스트 플레이어와 동기화할 수 있습니다.
|
|
139
75
|
|
|
140
76
|
```ts
|
|
141
77
|
sdk.events.seekTimeline({ clipId: "clip-42", clipPlayHead: 132.4 });
|
|
@@ -143,44 +79,44 @@ sdk.events.seekTimeline({ clipId: "clip-42", clipPlayHead: 132.4 });
|
|
|
143
79
|
|
|
144
80
|
### `destroy()`
|
|
145
81
|
|
|
146
|
-
|
|
82
|
+
모든 리스너를 해제하고, iframe 및 토글 버튼 장식을 제거하며, 내부 상태를 초기화합니다. 단일 페이지 애플리케이션 라우트를 언마운트할 때 호출하세요.
|
|
147
83
|
|
|
148
|
-
##
|
|
84
|
+
## 이벤트 시스템
|
|
149
85
|
|
|
150
|
-
|
|
86
|
+
이벤트는 `sdk.events` 헬퍼를 통해 제공됩니다. 모든 리스너는 구독 해제 함수를 반환합니다.
|
|
151
87
|
|
|
152
88
|
```ts
|
|
153
|
-
//
|
|
154
|
-
sdk.events.onChatInitiated(() => console.log("
|
|
155
|
-
sdk.events.onChatOpened(() => console.log("
|
|
156
|
-
sdk.events.onChatClosed(() => console.log("
|
|
89
|
+
// 채팅 라이프사이클 이벤트
|
|
90
|
+
sdk.events.onChatInitiated(() => console.log("채팅 초기화됨"));
|
|
91
|
+
sdk.events.onChatOpened(() => console.log("채팅 열림"));
|
|
92
|
+
sdk.events.onChatClosed(() => console.log("채팅 닫힘"));
|
|
157
93
|
|
|
158
|
-
//
|
|
94
|
+
// 타임라인 동기화
|
|
159
95
|
sdk.events.onTimelineSeek((playHead, clipId) => {
|
|
160
|
-
console.log("EduTap
|
|
96
|
+
console.log("EduTap이 타임라인 시크 요청", playHead, clipId);
|
|
161
97
|
});
|
|
162
98
|
|
|
163
|
-
//
|
|
99
|
+
// 알림 및 오버레이
|
|
164
100
|
sdk.events.onAlarmFadeIn((alarm) => {
|
|
165
|
-
console.log("
|
|
101
|
+
console.log("알람", alarm.message);
|
|
166
102
|
});
|
|
167
103
|
|
|
168
104
|
sdk.events.onPopUpOpen((popUp) => {
|
|
169
|
-
// popUp.html
|
|
105
|
+
// popUp.html에 렌더링된 스니펫이 포함됨
|
|
170
106
|
});
|
|
171
107
|
|
|
172
|
-
sdk.events.onPdfOpen(() => console.log("PDF
|
|
173
|
-
sdk.events.onPdfClose(() => console.log("PDF
|
|
108
|
+
sdk.events.onPdfOpen(() => console.log("PDF 오버레이 열림"));
|
|
109
|
+
sdk.events.onPdfClose(() => console.log("PDF 오버레이 닫힘"));
|
|
174
110
|
```
|
|
175
111
|
|
|
176
|
-
## TypeScript
|
|
112
|
+
## TypeScript 지원
|
|
177
113
|
|
|
178
|
-
|
|
114
|
+
타입 정의가 패키지에 포함되어 있습니다. 주요 export:
|
|
179
115
|
|
|
180
116
|
```ts
|
|
181
117
|
import type {
|
|
182
|
-
|
|
183
|
-
|
|
118
|
+
TapKitConfig,
|
|
119
|
+
TapKitInitParams,
|
|
184
120
|
Course,
|
|
185
121
|
ContainerStyle,
|
|
186
122
|
PositionType,
|
|
@@ -189,48 +125,9 @@ import type {
|
|
|
189
125
|
} from "@coxwave/tap-sdk";
|
|
190
126
|
```
|
|
191
127
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
## Version Management
|
|
195
|
-
|
|
196
|
-
### How It Works
|
|
128
|
+
## 보안 고려사항
|
|
197
129
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
```typescript
|
|
201
|
-
const CDN_LOADER_URL = 'https://files.edutap.ai/tap-sdk/loader.js';
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
The CDN loader (`tap-kit-core/loader.ts`) handles all version management:
|
|
205
|
-
1. Fetches `versions.json` to get the latest version
|
|
206
|
-
2. Loads the appropriate `tap-kit-{version}.js` with SRI verification
|
|
207
|
-
3. Initializes the actual SDK
|
|
208
|
-
|
|
209
|
-
### Deployment Workflow
|
|
210
|
-
|
|
211
|
-
**For SDK updates (most common):**
|
|
212
|
-
```bash
|
|
213
|
-
cd packages/tap-kit-core
|
|
214
|
-
pnpm build
|
|
215
|
-
./scripts/deploy-s3.sh
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
This deploys to CDN and all users automatically get the update.
|
|
219
|
-
|
|
220
|
-
**For npm package updates (rare):**
|
|
221
|
-
```bash
|
|
222
|
-
cd packages/tap-sdk
|
|
223
|
-
pnpm build
|
|
224
|
-
pnpm publish:npm
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
Only needed when the API surface changes (new methods, types, etc).
|
|
228
|
-
|
|
229
|
-
## Security Considerations
|
|
230
|
-
|
|
231
|
-
### Content Security Policy (CSP)
|
|
232
|
-
|
|
233
|
-
If your site uses CSP headers, add these directives:
|
|
130
|
+
사이트에서 Content Security Policy (CSP) 헤더를 사용하는 경우, 다음 지시문을 추가하세요:
|
|
234
131
|
|
|
235
132
|
```http
|
|
236
133
|
Content-Security-Policy:
|
|
@@ -240,59 +137,41 @@ Content-Security-Policy:
|
|
|
240
137
|
frame-src 'self' https://your-edutap-domain.com;
|
|
241
138
|
```
|
|
242
139
|
|
|
243
|
-
|
|
244
|
-
- `script-src` must include `https://files.edutap.ai` for CDN loading
|
|
245
|
-
- `style-src 'unsafe-inline'` is required for injected CSS (Vanilla Extract)
|
|
246
|
-
|
|
247
|
-
### Subresource Integrity (SRI)
|
|
248
|
-
|
|
249
|
-
The loader verifies CDN files using SHA-384 integrity checks:
|
|
250
|
-
|
|
251
|
-
```typescript
|
|
252
|
-
// In loader.ts
|
|
253
|
-
script.integrity = CDN_INTEGRITY;
|
|
254
|
-
script.crossOrigin = 'anonymous';
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
This ensures the loaded SDK hasn't been tampered with, even if CloudFront is compromised.
|
|
258
|
-
|
|
259
|
-
## Browser Support
|
|
140
|
+
## 브라우저 지원
|
|
260
141
|
|
|
261
142
|
- Chrome 60+
|
|
262
143
|
- Firefox 60+
|
|
263
144
|
- Safari 12+
|
|
264
145
|
- Edge 79+
|
|
265
146
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
## License
|
|
147
|
+
## 라이선스
|
|
269
148
|
|
|
270
149
|
MIT © 2025 Coxwave
|
|
271
150
|
|
|
272
|
-
##
|
|
151
|
+
## 속성
|
|
273
152
|
|
|
274
153
|
### `isOpen`
|
|
275
154
|
|
|
276
|
-
|
|
155
|
+
채팅 인터페이스가 현재 열려 있으면 `true`를 반환합니다.
|
|
277
156
|
|
|
278
157
|
```ts
|
|
279
158
|
if (sdk.isOpen) {
|
|
280
|
-
console.log("
|
|
159
|
+
console.log("채팅이 현재 열려 있습니다");
|
|
281
160
|
}
|
|
282
161
|
```
|
|
283
162
|
|
|
284
163
|
### `isInitialized`
|
|
285
164
|
|
|
286
|
-
|
|
165
|
+
SDK가 성공적으로 초기화되면 `true`를 반환합니다.
|
|
287
166
|
|
|
288
167
|
```ts
|
|
289
168
|
if (sdk.isInitialized) {
|
|
290
|
-
console.log("SDK
|
|
169
|
+
console.log("SDK 사용 준비 완료");
|
|
291
170
|
}
|
|
292
171
|
```
|
|
293
172
|
|
|
294
|
-
##
|
|
173
|
+
## 더 이상 사용되지 않는 헬퍼
|
|
295
174
|
|
|
296
|
-
- `initChat(options)` –
|
|
297
|
-
- `postChatInfo({ clipId, clipPlayHead })` –
|
|
298
|
-
- `getTimelineInfo({ callback })` –
|
|
175
|
+
- `initChat(options)` – `init(options)` 사용 권장; v1.0.0에서 제거 예정
|
|
176
|
+
- `postChatInfo({ clipId, clipPlayHead })` – `events.seekTimeline`의 별칭; v1.0.0에서 제거 예정
|
|
177
|
+
- `getTimelineInfo({ callback })` – `sdk.events.onTimelineSeek` 사용 권장; v1.0.0에서 제거 예정
|
package/dist/index.d.cts
CHANGED
|
@@ -2,16 +2,16 @@ import { AlarmMessageInstanceType } from '@coxwave/tap-messages';
|
|
|
2
2
|
export { AlarmMessageInstanceType, AlarmType } from '@coxwave/tap-messages';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* TapKit Type Definitions
|
|
6
6
|
*
|
|
7
7
|
* Re-exported types for API compatibility with the loader.
|
|
8
|
-
* These types match the actual SDK implementation in tap-
|
|
8
|
+
* These types match the actual SDK implementation in tap-kit-core.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
type
|
|
11
|
+
type TapKitConfig = {
|
|
12
12
|
apiKey: string;
|
|
13
13
|
};
|
|
14
|
-
type
|
|
14
|
+
type TapKitInitParams = {
|
|
15
15
|
buttonId: string;
|
|
16
16
|
course: Course;
|
|
17
17
|
container?: ContainerStyle;
|
|
@@ -40,21 +40,23 @@ type SeekTimelineParamsType = {
|
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
|
-
*
|
|
43
|
+
* TapKit wrapper - npm package wrapper
|
|
44
44
|
*
|
|
45
45
|
* Simply loads the CDN loader which handles version management and SDK loading.
|
|
46
46
|
* This keeps the npm package minimal and allows instant updates via CDN.
|
|
47
|
+
*
|
|
48
|
+
* Demo version: Automatically configures localStorage for demo environment.
|
|
47
49
|
*/
|
|
48
50
|
|
|
49
|
-
type
|
|
51
|
+
type TapKitConstructor = new (config: TapKitConfig) => TapKitInstance;
|
|
50
52
|
declare global {
|
|
51
53
|
interface Window {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
TapKit?: TapKitConstructor;
|
|
55
|
+
__TAP_KIT_LOADER_LOADED__?: boolean;
|
|
56
|
+
__TAP_KIT_LOADER_LOADING__?: Promise<void>;
|
|
55
57
|
}
|
|
56
58
|
}
|
|
57
|
-
interface
|
|
59
|
+
interface TapKitInstance {
|
|
58
60
|
events: {
|
|
59
61
|
seekTimeline: (params: SeekTimelineParamsType) => void;
|
|
60
62
|
onTimelineSeek: (callback: (clipPlayHead: number, clipId: string) => void) => void;
|
|
@@ -68,10 +70,11 @@ interface TapSDKInstance {
|
|
|
68
70
|
};
|
|
69
71
|
isOpen: boolean;
|
|
70
72
|
isInitialized: boolean;
|
|
71
|
-
|
|
73
|
+
readyPromise: Promise<void>;
|
|
74
|
+
init(params: TapKitInitParams): Promise<void>;
|
|
72
75
|
destroy(): void;
|
|
73
76
|
getVersion(): string;
|
|
74
|
-
initChat(params:
|
|
77
|
+
initChat(params: TapKitInitParams): Promise<void>;
|
|
75
78
|
postChatInfo(params: {
|
|
76
79
|
clipId: string;
|
|
77
80
|
clipPlayHead: number;
|
|
@@ -80,18 +83,20 @@ interface TapSDKInstance {
|
|
|
80
83
|
callback: (clipPlayHead: number, clipId: string) => void;
|
|
81
84
|
}): Promise<void>;
|
|
82
85
|
}
|
|
86
|
+
declare const SDK_INSTANCE: unique symbol;
|
|
87
|
+
declare const SDK_INSTANCE_LOADING: unique symbol;
|
|
83
88
|
/**
|
|
84
|
-
*
|
|
89
|
+
* TapKit Wrapper Class
|
|
85
90
|
*
|
|
86
91
|
* Loads the CDN loader and proxies all calls to the actual SDK
|
|
87
92
|
*/
|
|
88
|
-
declare class
|
|
89
|
-
private
|
|
90
|
-
private
|
|
91
|
-
|
|
92
|
-
constructor(config: TapSDKConfig);
|
|
93
|
+
declare class TapKit implements TapKitInstance {
|
|
94
|
+
private [SDK_INSTANCE]?;
|
|
95
|
+
private [SDK_INSTANCE_LOADING];
|
|
96
|
+
constructor(config: TapKitConfig);
|
|
93
97
|
private loadAndInitialize;
|
|
94
98
|
private ensureLoaded;
|
|
99
|
+
get readyPromise(): Promise<void>;
|
|
95
100
|
get events(): {
|
|
96
101
|
seekTimeline: (params: SeekTimelineParamsType) => void;
|
|
97
102
|
onTimelineSeek: (callback: (clipPlayHead: number, clipId: string) => void) => void;
|
|
@@ -105,10 +110,10 @@ declare class TapSDK implements TapSDKInstance {
|
|
|
105
110
|
};
|
|
106
111
|
get isOpen(): boolean;
|
|
107
112
|
get isInitialized(): boolean;
|
|
108
|
-
init(params:
|
|
113
|
+
init(params: TapKitInitParams): Promise<void>;
|
|
109
114
|
destroy(): void;
|
|
110
115
|
getVersion(): string;
|
|
111
|
-
initChat(params:
|
|
116
|
+
initChat(params: TapKitInitParams): Promise<void>;
|
|
112
117
|
postChatInfo(params: {
|
|
113
118
|
clipId: string;
|
|
114
119
|
clipPlayHead: number;
|
|
@@ -118,4 +123,4 @@ declare class TapSDK implements TapSDKInstance {
|
|
|
118
123
|
}): Promise<void>;
|
|
119
124
|
}
|
|
120
125
|
|
|
121
|
-
export { type ContainerStyle, type Course, type PositionType, type SeekTimelineParamsType, type
|
|
126
|
+
export { type ContainerStyle, type Course, type PositionType, type SeekTimelineParamsType, type TapKitInstance as TapKit, type TapKitConfig, type TapKitConstructor, type TapKitInitParams, TapKit as default };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,16 +2,16 @@ import { AlarmMessageInstanceType } from '@coxwave/tap-messages';
|
|
|
2
2
|
export { AlarmMessageInstanceType, AlarmType } from '@coxwave/tap-messages';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* TapKit Type Definitions
|
|
6
6
|
*
|
|
7
7
|
* Re-exported types for API compatibility with the loader.
|
|
8
|
-
* These types match the actual SDK implementation in tap-
|
|
8
|
+
* These types match the actual SDK implementation in tap-kit-core.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
type
|
|
11
|
+
type TapKitConfig = {
|
|
12
12
|
apiKey: string;
|
|
13
13
|
};
|
|
14
|
-
type
|
|
14
|
+
type TapKitInitParams = {
|
|
15
15
|
buttonId: string;
|
|
16
16
|
course: Course;
|
|
17
17
|
container?: ContainerStyle;
|
|
@@ -40,21 +40,23 @@ type SeekTimelineParamsType = {
|
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
|
-
*
|
|
43
|
+
* TapKit wrapper - npm package wrapper
|
|
44
44
|
*
|
|
45
45
|
* Simply loads the CDN loader which handles version management and SDK loading.
|
|
46
46
|
* This keeps the npm package minimal and allows instant updates via CDN.
|
|
47
|
+
*
|
|
48
|
+
* Demo version: Automatically configures localStorage for demo environment.
|
|
47
49
|
*/
|
|
48
50
|
|
|
49
|
-
type
|
|
51
|
+
type TapKitConstructor = new (config: TapKitConfig) => TapKitInstance;
|
|
50
52
|
declare global {
|
|
51
53
|
interface Window {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
TapKit?: TapKitConstructor;
|
|
55
|
+
__TAP_KIT_LOADER_LOADED__?: boolean;
|
|
56
|
+
__TAP_KIT_LOADER_LOADING__?: Promise<void>;
|
|
55
57
|
}
|
|
56
58
|
}
|
|
57
|
-
interface
|
|
59
|
+
interface TapKitInstance {
|
|
58
60
|
events: {
|
|
59
61
|
seekTimeline: (params: SeekTimelineParamsType) => void;
|
|
60
62
|
onTimelineSeek: (callback: (clipPlayHead: number, clipId: string) => void) => void;
|
|
@@ -68,10 +70,11 @@ interface TapSDKInstance {
|
|
|
68
70
|
};
|
|
69
71
|
isOpen: boolean;
|
|
70
72
|
isInitialized: boolean;
|
|
71
|
-
|
|
73
|
+
readyPromise: Promise<void>;
|
|
74
|
+
init(params: TapKitInitParams): Promise<void>;
|
|
72
75
|
destroy(): void;
|
|
73
76
|
getVersion(): string;
|
|
74
|
-
initChat(params:
|
|
77
|
+
initChat(params: TapKitInitParams): Promise<void>;
|
|
75
78
|
postChatInfo(params: {
|
|
76
79
|
clipId: string;
|
|
77
80
|
clipPlayHead: number;
|
|
@@ -80,18 +83,20 @@ interface TapSDKInstance {
|
|
|
80
83
|
callback: (clipPlayHead: number, clipId: string) => void;
|
|
81
84
|
}): Promise<void>;
|
|
82
85
|
}
|
|
86
|
+
declare const SDK_INSTANCE: unique symbol;
|
|
87
|
+
declare const SDK_INSTANCE_LOADING: unique symbol;
|
|
83
88
|
/**
|
|
84
|
-
*
|
|
89
|
+
* TapKit Wrapper Class
|
|
85
90
|
*
|
|
86
91
|
* Loads the CDN loader and proxies all calls to the actual SDK
|
|
87
92
|
*/
|
|
88
|
-
declare class
|
|
89
|
-
private
|
|
90
|
-
private
|
|
91
|
-
|
|
92
|
-
constructor(config: TapSDKConfig);
|
|
93
|
+
declare class TapKit implements TapKitInstance {
|
|
94
|
+
private [SDK_INSTANCE]?;
|
|
95
|
+
private [SDK_INSTANCE_LOADING];
|
|
96
|
+
constructor(config: TapKitConfig);
|
|
93
97
|
private loadAndInitialize;
|
|
94
98
|
private ensureLoaded;
|
|
99
|
+
get readyPromise(): Promise<void>;
|
|
95
100
|
get events(): {
|
|
96
101
|
seekTimeline: (params: SeekTimelineParamsType) => void;
|
|
97
102
|
onTimelineSeek: (callback: (clipPlayHead: number, clipId: string) => void) => void;
|
|
@@ -105,10 +110,10 @@ declare class TapSDK implements TapSDKInstance {
|
|
|
105
110
|
};
|
|
106
111
|
get isOpen(): boolean;
|
|
107
112
|
get isInitialized(): boolean;
|
|
108
|
-
init(params:
|
|
113
|
+
init(params: TapKitInitParams): Promise<void>;
|
|
109
114
|
destroy(): void;
|
|
110
115
|
getVersion(): string;
|
|
111
|
-
initChat(params:
|
|
116
|
+
initChat(params: TapKitInitParams): Promise<void>;
|
|
112
117
|
postChatInfo(params: {
|
|
113
118
|
clipId: string;
|
|
114
119
|
clipPlayHead: number;
|
|
@@ -118,4 +123,4 @@ declare class TapSDK implements TapSDKInstance {
|
|
|
118
123
|
}): Promise<void>;
|
|
119
124
|
}
|
|
120
125
|
|
|
121
|
-
export { type ContainerStyle, type Course, type PositionType, type SeekTimelineParamsType, type
|
|
126
|
+
export { type ContainerStyle, type Course, type PositionType, type SeekTimelineParamsType, type TapKitInstance as TapKit, type TapKitConfig, type TapKitConstructor, type TapKitInitParams, TapKit as default };
|
package/dist/index.global.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var TapSDK=(function(){'use strict';var
|
|
2
|
-
return
|
|
1
|
+
var TapSDK=(function(){'use strict';var T=Object.defineProperty;var _=(n,e,i)=>e in n?T(n,e,{enumerable:true,configurable:true,writable:true,value:i}):n[e]=i;var r=(n,e,i)=>_(n,typeof e!="symbol"?e+"":e,i);typeof localStorage<"u"&&(localStorage.setItem("tap-url-storage",JSON.stringify({state:{tapUrl:"https://demo-edutap.vercel.app"}})),localStorage.setItem("tap-api-url-storage",JSON.stringify({state:{apiUrl:"https://tapadminstaging.coxwave.link"}})),localStorage.setItem("tap-environment","demo"),console.log("[TapSDK Demo] Environment configured:",{tapUrl:"https://demo-edutap.vercel.app",apiUrl:"https://tapadminstaging.coxwave.link",environment:"demo"}));var s="https://files.edutap.ai/tap-sdk/loader.js";function v(){if(window.__TAP_KIT_LOADER_LOADED__&&window.TapKit)return Promise.resolve();if(window.__TAP_KIT_LOADER_LOADING__)return window.__TAP_KIT_LOADER_LOADING__;let n=new Promise((e,i)=>{if(typeof document>"u"){i(new Error("TapKit requires browser environment (document is undefined)"));return}let o=document.createElement("script");o.src=s,o.async=true,o.onload=()=>{let a=()=>{window.TapKit?(window.__TAP_KIT_LOADER_LOADED__=true,window.__TAP_KIT_LOADER_LOADING__=void 0,e()):setTimeout(a,50);};a();},o.onerror=()=>{window.__TAP_KIT_LOADER_LOADING__=void 0,i(new Error(`Failed to load TapKit CDN loader: ${s}`));};let d=document.querySelector(`script[src="${s}"]`);d?(d.addEventListener("load",()=>{let a=()=>{window.TapKit?e():setTimeout(a,50);};a();}),d.addEventListener("error",()=>i(new Error(`Failed to load TapKit CDN loader: ${s}`)))):document.head.appendChild(o);});return window.__TAP_KIT_LOADER_LOADING__=n,n}var t=Symbol("sdkInstance"),l=Symbol("sdkInstanceLoading"),c,m;m=t,c=l;var p=class{constructor(e){r(this,m);r(this,c);this[l]=this.loadAndInitialize(e);}async loadAndInitialize(e){if(console.log("[tap-sdk] Loading CDN loader..."),await v(),console.log("[tap-sdk] CDN loader loaded, window.TapKit:",!!window.TapKit),!window.TapKit)throw new Error("TapKit not available after loading CDN loader");console.log("[tap-sdk] Creating TapKit instance..."),this[t]=new window.TapKit(e),console.log("[tap-sdk] TapKit instance created");}async ensureLoaded(){if(console.log("[tap-sdk] ensureLoaded: waiting for SDK_INSTANCE_LOADING..."),await this[l],console.log("[tap-sdk] ensureLoaded: SDK_INSTANCE_LOADING completed"),!this[t])throw new Error("TapKit instance not initialized");return console.log("[tap-sdk] ensureLoaded: returning SDK instance"),this[t]}get readyPromise(){return this.ensureLoaded().then(e=>e.readyPromise)}get events(){return {seekTimeline:e=>{this.ensureLoaded().then(i=>i.events.seekTimeline(e));},onTimelineSeek:e=>{this.ensureLoaded().then(i=>i.events.onTimelineSeek(e));},onChatInitiated:e=>{this.ensureLoaded().then(i=>i.events.onChatInitiated(e));},onChatOpened:e=>{this.ensureLoaded().then(i=>i.events.onChatOpened(e));},onChatClosed:e=>{this.ensureLoaded().then(i=>i.events.onChatClosed(e));},onAlarmFadeIn:e=>{this.ensureLoaded().then(i=>i.events.onAlarmFadeIn(e));},onPopUpOpen:e=>{this.ensureLoaded().then(i=>i.events.onPopUpOpen(e));},onPdfOpen:e=>{this.ensureLoaded().then(i=>i.events.onPdfOpen(e));},onPdfClose:e=>{this.ensureLoaded().then(i=>i.events.onPdfClose(e));}}}get isOpen(){return this[t]?.isOpen??false}get isInitialized(){return this[t]?.isInitialized??false}async init(e){return (await this.ensureLoaded()).init(e)}destroy(){this[t]&&this[t].destroy();}getVersion(){return this[t]?.getVersion()??"Not initialized"}async initChat(e){return (await this.ensureLoaded()).initChat(e)}async postChatInfo(e){return (await this.ensureLoaded()).postChatInfo(e)}async getTimelineInfo(e){return (await this.ensureLoaded()).getTimelineInfo(e)}},h=p;
|
|
2
|
+
return h;})();//# sourceMappingURL=index.global.js.map
|
|
3
3
|
//# sourceMappingURL=index.global.js.map
|
package/dist/index.global.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../index.ts"],"names":["CDN_LOADER_URL","loadCDNLoader","loadingPromise","resolve","reject","script","checkSDK","existingScript","TapSDK","config","__publicField","params","sdk","callback","handler","index_default"],"mappings":"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","file":"index.global.js","sourcesContent":["/**\n * TapSDK - npm package wrapper\n *\n * Simply loads the CDN loader which handles version management and SDK loading.\n * This keeps the npm package minimal and allows instant updates via CDN.\n */\n\nimport type {\n TapSDKConfig,\n TapSDKInitParams,\n Course,\n ContainerStyle,\n PositionType,\n SeekTimelineParamsType,\n AlarmMessageInstanceType,\n AlarmType,\n} from './types';\n\nconst CDN_LOADER_URL = 'https://files.edutap.ai/tap-sdk/loader.js';\n\n// Global namespace for loaded SDK\n// Export type for IIFE bundles loaded via window.TapSDK\nexport type TapSDKConstructor = new (config: TapSDKConfig) => TapSDKInstance;\n\ndeclare global {\n interface Window {\n TapSDK?: TapSDKConstructor;\n __TAP_SDK_LOADER_LOADED__?: boolean;\n __TAP_SDK_LOADER_LOADING__?: Promise<void>;\n }\n}\n\ninterface TapSDKInstance {\n events: {\n seekTimeline: (params: SeekTimelineParamsType) => void;\n onTimelineSeek: (callback: (clipPlayHead: number, clipId: string) => void) => void;\n onChatInitiated: (handler: () => void) => void;\n onChatOpened: (handler: () => void) => void;\n onChatClosed: (handler: () => void) => void;\n onAlarmFadeIn: (handler: (messageInfo: AlarmMessageInstanceType) => void) => void;\n onPopUpOpen: (handler: (popUpInfo: any) => void) => void;\n onPdfOpen: (handler: () => void) => void;\n onPdfClose: (handler: () => void) => void;\n };\n isOpen: boolean;\n isInitialized: boolean;\n init(params: TapSDKInitParams): Promise<void>;\n destroy(): void;\n getVersion(): string;\n // Deprecated methods\n initChat(params: TapSDKInitParams): Promise<void>;\n postChatInfo(params: { clipId: string; clipPlayHead: number }): Promise<void>;\n getTimelineInfo(params: { callback: (clipPlayHead: number, clipId: string) => void }): Promise<void>;\n}\n\n/**\n * Loads the CDN loader script\n * The loader will then fetch versions.json and load the appropriate SDK version\n */\nfunction loadCDNLoader(): Promise<void> {\n // If already loaded, return immediately\n if (window.__TAP_SDK_LOADER_LOADED__ && window.TapSDK) {\n return Promise.resolve();\n }\n\n // If currently loading, return the existing promise\n if (window.__TAP_SDK_LOADER_LOADING__) {\n return window.__TAP_SDK_LOADER_LOADING__;\n }\n\n // Create loading promise\n const loadingPromise = new Promise<void>((resolve, reject) => {\n if (typeof document === 'undefined') {\n reject(new Error('TapSDK requires browser environment (document is undefined)'));\n return;\n }\n\n const script = document.createElement('script');\n script.src = CDN_LOADER_URL;\n script.async = true;\n\n script.onload = () => {\n // The loader script will load the actual SDK\n // We need to wait a bit for the loader to fetch and load the SDK\n const checkSDK = () => {\n if (window.TapSDK) {\n window.__TAP_SDK_LOADER_LOADED__ = true;\n window.__TAP_SDK_LOADER_LOADING__ = undefined;\n resolve();\n } else {\n // Check again after a short delay\n setTimeout(checkSDK, 50);\n }\n };\n checkSDK();\n };\n\n script.onerror = () => {\n window.__TAP_SDK_LOADER_LOADING__ = undefined;\n reject(new Error(`Failed to load TapSDK CDN loader: ${CDN_LOADER_URL}`));\n };\n\n // Check if script already exists\n const existingScript = document.querySelector(`script[src=\"${CDN_LOADER_URL}\"]`);\n if (existingScript) {\n // Script already added but not yet loaded\n existingScript.addEventListener('load', () => {\n const checkSDK = () => {\n if (window.TapSDK) resolve();\n else setTimeout(checkSDK, 50);\n };\n checkSDK();\n });\n existingScript.addEventListener('error', () =>\n reject(new Error(`Failed to load TapSDK CDN loader: ${CDN_LOADER_URL}`))\n );\n } else {\n document.head.appendChild(script);\n }\n });\n\n window.__TAP_SDK_LOADER_LOADING__ = loadingPromise;\n return loadingPromise;\n}\n\n/**\n * TapSDK Wrapper Class\n *\n * Loads the CDN loader and proxies all calls to the actual SDK\n */\nclass TapSDK implements TapSDKInstance {\n private config: TapSDKConfig;\n private sdkInstance?: TapSDKInstance;\n private loadPromise: Promise<void>;\n\n constructor(config: TapSDKConfig) {\n this.config = config;\n this.loadPromise = this.loadAndInitialize();\n }\n\n private async loadAndInitialize(): Promise<void> {\n await loadCDNLoader();\n\n if (!window.TapSDK) {\n throw new Error('TapSDK not available after loading CDN loader');\n }\n\n this.sdkInstance = new window.TapSDK(this.config);\n }\n\n private async ensureLoaded(): Promise<TapSDKInstance> {\n await this.loadPromise;\n if (!this.sdkInstance) {\n throw new Error('TapSDK instance not initialized');\n }\n return this.sdkInstance;\n }\n\n // Public API - all methods proxy to the loaded SDK\n get events() {\n return {\n seekTimeline: (params: SeekTimelineParamsType) => {\n this.ensureLoaded().then(sdk => sdk.events.seekTimeline(params));\n },\n onTimelineSeek: (callback: (clipPlayHead: number, clipId: string) => void) => {\n this.ensureLoaded().then(sdk => sdk.events.onTimelineSeek(callback));\n },\n onChatInitiated: (handler: () => void) => {\n this.ensureLoaded().then(sdk => sdk.events.onChatInitiated(handler));\n },\n onChatOpened: (handler: () => void) => {\n this.ensureLoaded().then(sdk => sdk.events.onChatOpened(handler));\n },\n onChatClosed: (handler: () => void) => {\n this.ensureLoaded().then(sdk => sdk.events.onChatClosed(handler));\n },\n onAlarmFadeIn: (handler: (messageInfo: AlarmMessageInstanceType) => void) => {\n this.ensureLoaded().then(sdk => sdk.events.onAlarmFadeIn(handler));\n },\n onPopUpOpen: (handler: (popUpInfo: any) => void) => {\n this.ensureLoaded().then(sdk => sdk.events.onPopUpOpen(handler));\n },\n onPdfOpen: (handler: () => void) => {\n this.ensureLoaded().then(sdk => sdk.events.onPdfOpen(handler));\n },\n onPdfClose: (handler: () => void) => {\n this.ensureLoaded().then(sdk => sdk.events.onPdfClose(handler));\n },\n };\n }\n\n get isOpen(): boolean {\n return this.sdkInstance?.isOpen ?? false;\n }\n\n get isInitialized(): boolean {\n return this.sdkInstance?.isInitialized ?? false;\n }\n\n async init(params: TapSDKInitParams): Promise<void> {\n const sdk = await this.ensureLoaded();\n return sdk.init(params);\n }\n\n destroy(): void {\n if (this.sdkInstance) {\n this.sdkInstance.destroy();\n }\n }\n\n getVersion(): string {\n return this.sdkInstance?.getVersion() ?? 'Not initialized';\n }\n\n // Deprecated methods\n async initChat(params: TapSDKInitParams): Promise<void> {\n const sdk = await this.ensureLoaded();\n return sdk.initChat(params);\n }\n\n async postChatInfo(params: { clipId: string; clipPlayHead: number }): Promise<void> {\n const sdk = await this.ensureLoaded();\n return sdk.postChatInfo(params);\n }\n\n async getTimelineInfo(params: { callback: (clipPlayHead: number, clipId: string) => void }): Promise<void> {\n const sdk = await this.ensureLoaded();\n return sdk.getTimelineInfo(params);\n }\n}\n\n// Export the SDK class as default (for: import TapSDK from '@coxwave/tap-sdk')\nexport default TapSDK;\n\n// Export TapSDK instance type (for: import type { TapSDK } from '@coxwave/tap-sdk')\nexport type { TapSDKInstance as TapSDK };\n\n// Keep TapSDKInstance for backward compatibility\nexport type { TapSDKInstance };\n\n// Re-export types for API compatibility\nexport type {\n TapSDKConfig,\n TapSDKInitParams,\n Course,\n ContainerStyle,\n PositionType,\n SeekTimelineParamsType,\n AlarmMessageInstanceType,\n AlarmType,\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../index.ts"],"names":["CDN_LOADER_URL","loadCDNLoader","loadingPromise","resolve","reject","script","checkSDK","existingScript","SDK_INSTANCE","SDK_INSTANCE_LOADING","_a","_b","TapKit","config","__publicField","sdk","params","callback","handler","index_default"],"mappings":"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","file":"index.global.js","sourcesContent":["/**\n * TapKit wrapper - npm package wrapper\n *\n * Simply loads the CDN loader which handles version management and SDK loading.\n * This keeps the npm package minimal and allows instant updates via CDN.\n *\n * Demo version: Automatically configures localStorage for demo environment.\n */\n\n// Configure demo environment if this is the demo version\nif (typeof localStorage !== \"undefined\") {\n // Demo edutap FE URL\n localStorage.setItem(\n \"tap-url-storage\",\n JSON.stringify({\n state: { tapUrl: \"https://demo-edutap.vercel.app\" },\n })\n );\n\n // Demo API URL\n localStorage.setItem(\n \"tap-api-url-storage\",\n JSON.stringify({\n state: { apiUrl: \"https://tapadminstaging.coxwave.link\" },\n })\n );\n\n // Demo environment flag (enables console logging)\n localStorage.setItem(\"tap-environment\", \"demo\");\n\n console.log(\"[TapSDK Demo] Environment configured:\", {\n tapUrl: \"https://demo-edutap.vercel.app\",\n apiUrl: \"https://tapadminstaging.coxwave.link\",\n environment: \"demo\",\n });\n}\n\nimport type {\n TapKitConfig,\n TapKitInitParams,\n Course,\n ContainerStyle,\n PositionType,\n SeekTimelineParamsType,\n AlarmMessageInstanceType,\n AlarmType,\n} from \"./types\";\n\nconst CDN_LOADER_URL = \"https://files.edutap.ai/tap-sdk/loader.js\";\n\n// Global namespace for loaded SDK\n// Export type for IIFE bundles loaded via window.TapKit\nexport type TapKitConstructor = new (config: TapKitConfig) => TapKitInstance;\n\ndeclare global {\n interface Window {\n TapKit?: TapKitConstructor;\n __TAP_KIT_LOADER_LOADED__?: boolean;\n __TAP_KIT_LOADER_LOADING__?: Promise<void>;\n }\n}\n\ninterface TapKitInstance {\n events: {\n seekTimeline: (params: SeekTimelineParamsType) => void;\n onTimelineSeek: (\n callback: (clipPlayHead: number, clipId: string) => void\n ) => void;\n onChatInitiated: (handler: () => void) => void;\n onChatOpened: (handler: () => void) => void;\n onChatClosed: (handler: () => void) => void;\n onAlarmFadeIn: (\n handler: (messageInfo: AlarmMessageInstanceType) => void\n ) => void;\n onPopUpOpen: (handler: (popUpInfo: any) => void) => void;\n onPdfOpen: (handler: () => void) => void;\n onPdfClose: (handler: () => void) => void;\n };\n isOpen: boolean;\n isInitialized: boolean;\n readyPromise: Promise<void>;\n init(params: TapKitInitParams): Promise<void>;\n destroy(): void;\n getVersion(): string;\n // Deprecated methods\n initChat(params: TapKitInitParams): Promise<void>;\n postChatInfo(params: { clipId: string; clipPlayHead: number }): Promise<void>;\n getTimelineInfo(params: {\n callback: (clipPlayHead: number, clipId: string) => void;\n }): Promise<void>;\n}\n\n/**\n * Loads the CDN loader script\n * The loader will then fetch versions.json and load the appropriate SDK version\n */\nfunction loadCDNLoader(): Promise<void> {\n // If already loaded, return immediately\n if (window.__TAP_KIT_LOADER_LOADED__ && window.TapKit) {\n return Promise.resolve();\n }\n\n // If currently loading, return the existing promise\n if (window.__TAP_KIT_LOADER_LOADING__) {\n return window.__TAP_KIT_LOADER_LOADING__;\n }\n\n // Create loading promise\n const loadingPromise = new Promise<void>((resolve, reject) => {\n if (typeof document === \"undefined\") {\n reject(\n new Error(\"TapKit requires browser environment (document is undefined)\")\n );\n return;\n }\n\n const script = document.createElement(\"script\");\n script.src = CDN_LOADER_URL;\n script.async = true;\n\n script.onload = () => {\n // The loader script will load the actual SDK\n // We need to wait a bit for the loader to fetch and load the SDK\n const checkSDK = () => {\n if (window.TapKit) {\n window.__TAP_KIT_LOADER_LOADED__ = true;\n window.__TAP_KIT_LOADER_LOADING__ = undefined;\n resolve();\n } else {\n // Check again after a short delay\n setTimeout(checkSDK, 50);\n }\n };\n checkSDK();\n };\n\n script.onerror = () => {\n window.__TAP_KIT_LOADER_LOADING__ = undefined;\n reject(new Error(`Failed to load TapKit CDN loader: ${CDN_LOADER_URL}`));\n };\n\n // Check if script already exists\n const existingScript = document.querySelector(\n `script[src=\"${CDN_LOADER_URL}\"]`\n );\n if (existingScript) {\n // Script already added but not yet loaded\n existingScript.addEventListener(\"load\", () => {\n const checkSDK = () => {\n if (window.TapKit) resolve();\n else setTimeout(checkSDK, 50);\n };\n checkSDK();\n });\n existingScript.addEventListener(\"error\", () =>\n reject(new Error(`Failed to load TapKit CDN loader: ${CDN_LOADER_URL}`))\n );\n } else {\n document.head.appendChild(script);\n }\n });\n\n window.__TAP_KIT_LOADER_LOADING__ = loadingPromise;\n return loadingPromise;\n}\n\n// Use Symbol to hide SDK instance from enumeration\nconst SDK_INSTANCE = Symbol(\"sdkInstance\");\nconst SDK_INSTANCE_LOADING = Symbol(\"sdkInstanceLoading\");\n\n/**\n * TapKit Wrapper Class\n *\n * Loads the CDN loader and proxies all calls to the actual SDK\n */\nclass TapKit implements TapKitInstance {\n private [SDK_INSTANCE]?: TapKitInstance;\n private [SDK_INSTANCE_LOADING]: Promise<void>;\n\n constructor(config: TapKitConfig) {\n this[SDK_INSTANCE_LOADING] = this.loadAndInitialize(config);\n }\n\n private async loadAndInitialize(config: TapKitConfig): Promise<void> {\n console.log(\"[tap-sdk] Loading CDN loader...\");\n await loadCDNLoader();\n console.log(\"[tap-sdk] CDN loader loaded, window.TapKit:\", !!window.TapKit);\n\n if (!window.TapKit) {\n throw new Error(\"TapKit not available after loading CDN loader\");\n }\n\n console.log(\"[tap-sdk] Creating TapKit instance...\");\n this[SDK_INSTANCE] = new window.TapKit(config);\n console.log(\"[tap-sdk] TapKit instance created\");\n }\n\n private async ensureLoaded(): Promise<TapKitInstance> {\n console.log(\"[tap-sdk] ensureLoaded: waiting for SDK_INSTANCE_LOADING...\");\n await this[SDK_INSTANCE_LOADING]; // Wait for SDK instance to be created\n console.log(\"[tap-sdk] ensureLoaded: SDK_INSTANCE_LOADING completed\");\n\n if (!this[SDK_INSTANCE]) {\n throw new Error(\"TapKit instance not initialized\");\n }\n\n console.log(\"[tap-sdk] ensureLoaded: returning SDK instance\");\n return this[SDK_INSTANCE];\n }\n\n // Expose tap-kit-core's readyPromise for advanced users\n // This resolves after init() is called and tap-kit-core is fully initialized\n get readyPromise(): Promise<void> {\n return this.ensureLoaded().then((sdk) => sdk.readyPromise);\n }\n\n // Public API - all methods proxy to the loaded SDK\n get events() {\n return {\n seekTimeline: (params: SeekTimelineParamsType) => {\n this.ensureLoaded().then((sdk) => sdk.events.seekTimeline(params));\n },\n onTimelineSeek: (\n callback: (clipPlayHead: number, clipId: string) => void\n ) => {\n this.ensureLoaded().then((sdk) => sdk.events.onTimelineSeek(callback));\n },\n onChatInitiated: (handler: () => void) => {\n this.ensureLoaded().then((sdk) => sdk.events.onChatInitiated(handler));\n },\n onChatOpened: (handler: () => void) => {\n this.ensureLoaded().then((sdk) => sdk.events.onChatOpened(handler));\n },\n onChatClosed: (handler: () => void) => {\n this.ensureLoaded().then((sdk) => sdk.events.onChatClosed(handler));\n },\n onAlarmFadeIn: (\n handler: (messageInfo: AlarmMessageInstanceType) => void\n ) => {\n this.ensureLoaded().then((sdk) => sdk.events.onAlarmFadeIn(handler));\n },\n onPopUpOpen: (handler: (popUpInfo: any) => void) => {\n this.ensureLoaded().then((sdk) => sdk.events.onPopUpOpen(handler));\n },\n onPdfOpen: (handler: () => void) => {\n this.ensureLoaded().then((sdk) => sdk.events.onPdfOpen(handler));\n },\n onPdfClose: (handler: () => void) => {\n this.ensureLoaded().then((sdk) => sdk.events.onPdfClose(handler));\n },\n };\n }\n\n get isOpen(): boolean {\n return this[SDK_INSTANCE]?.isOpen ?? false;\n }\n\n get isInitialized(): boolean {\n return this[SDK_INSTANCE]?.isInitialized ?? false;\n }\n\n async init(params: TapKitInitParams): Promise<void> {\n const sdk = await this.ensureLoaded();\n return sdk.init(params);\n }\n\n destroy(): void {\n if (this[SDK_INSTANCE]) {\n this[SDK_INSTANCE].destroy();\n }\n }\n\n getVersion(): string {\n return this[SDK_INSTANCE]?.getVersion() ?? \"Not initialized\";\n }\n\n // Deprecated methods\n async initChat(params: TapKitInitParams): Promise<void> {\n const sdk = await this.ensureLoaded();\n return sdk.initChat(params);\n }\n\n async postChatInfo(params: {\n clipId: string;\n clipPlayHead: number;\n }): Promise<void> {\n const sdk = await this.ensureLoaded();\n return sdk.postChatInfo(params);\n }\n\n async getTimelineInfo(params: {\n callback: (clipPlayHead: number, clipId: string) => void;\n }): Promise<void> {\n const sdk = await this.ensureLoaded();\n return sdk.getTimelineInfo(params);\n }\n}\n\n// Export the SDK class as default (for: import TapKit from '@coxwave/tap-sdk')\nexport default TapKit;\n\n// Export TapKit instance type (for: import type { TapKit } from '@coxwave/tap-sdk')\nexport type { TapKitInstance as TapKit };\n\n// Re-export types for API compatibility\nexport type {\n TapKitConfig,\n TapKitInitParams,\n Course,\n ContainerStyle,\n PositionType,\n SeekTimelineParamsType,\n AlarmMessageInstanceType,\n AlarmType,\n};\n"]}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
'use strict';var
|
|
2
|
-
module.exports=
|
|
1
|
+
'use strict';var T=Object.defineProperty;var _=(n,e,i)=>e in n?T(n,e,{enumerable:true,configurable:true,writable:true,value:i}):n[e]=i;var r=(n,e,i)=>_(n,typeof e!="symbol"?e+"":e,i);typeof localStorage<"u"&&(localStorage.setItem("tap-url-storage",JSON.stringify({state:{tapUrl:"https://demo-edutap.vercel.app"}})),localStorage.setItem("tap-api-url-storage",JSON.stringify({state:{apiUrl:"https://tapadminstaging.coxwave.link"}})),localStorage.setItem("tap-environment","demo"),console.log("[TapSDK Demo] Environment configured:",{tapUrl:"https://demo-edutap.vercel.app",apiUrl:"https://tapadminstaging.coxwave.link",environment:"demo"}));var s="https://files.edutap.ai/tap-sdk/loader.js";function v(){if(window.__TAP_KIT_LOADER_LOADED__&&window.TapKit)return Promise.resolve();if(window.__TAP_KIT_LOADER_LOADING__)return window.__TAP_KIT_LOADER_LOADING__;let n=new Promise((e,i)=>{if(typeof document>"u"){i(new Error("TapKit requires browser environment (document is undefined)"));return}let o=document.createElement("script");o.src=s,o.async=true,o.onload=()=>{let a=()=>{window.TapKit?(window.__TAP_KIT_LOADER_LOADED__=true,window.__TAP_KIT_LOADER_LOADING__=void 0,e()):setTimeout(a,50);};a();},o.onerror=()=>{window.__TAP_KIT_LOADER_LOADING__=void 0,i(new Error(`Failed to load TapKit CDN loader: ${s}`));};let d=document.querySelector(`script[src="${s}"]`);d?(d.addEventListener("load",()=>{let a=()=>{window.TapKit?e():setTimeout(a,50);};a();}),d.addEventListener("error",()=>i(new Error(`Failed to load TapKit CDN loader: ${s}`)))):document.head.appendChild(o);});return window.__TAP_KIT_LOADER_LOADING__=n,n}var t=Symbol("sdkInstance"),l=Symbol("sdkInstanceLoading"),c,m;m=t,c=l;var p=class{constructor(e){r(this,m);r(this,c);this[l]=this.loadAndInitialize(e);}async loadAndInitialize(e){if(console.log("[tap-sdk] Loading CDN loader..."),await v(),console.log("[tap-sdk] CDN loader loaded, window.TapKit:",!!window.TapKit),!window.TapKit)throw new Error("TapKit not available after loading CDN loader");console.log("[tap-sdk] Creating TapKit instance..."),this[t]=new window.TapKit(e),console.log("[tap-sdk] TapKit instance created");}async ensureLoaded(){if(console.log("[tap-sdk] ensureLoaded: waiting for SDK_INSTANCE_LOADING..."),await this[l],console.log("[tap-sdk] ensureLoaded: SDK_INSTANCE_LOADING completed"),!this[t])throw new Error("TapKit instance not initialized");return console.log("[tap-sdk] ensureLoaded: returning SDK instance"),this[t]}get readyPromise(){return this.ensureLoaded().then(e=>e.readyPromise)}get events(){return {seekTimeline:e=>{this.ensureLoaded().then(i=>i.events.seekTimeline(e));},onTimelineSeek:e=>{this.ensureLoaded().then(i=>i.events.onTimelineSeek(e));},onChatInitiated:e=>{this.ensureLoaded().then(i=>i.events.onChatInitiated(e));},onChatOpened:e=>{this.ensureLoaded().then(i=>i.events.onChatOpened(e));},onChatClosed:e=>{this.ensureLoaded().then(i=>i.events.onChatClosed(e));},onAlarmFadeIn:e=>{this.ensureLoaded().then(i=>i.events.onAlarmFadeIn(e));},onPopUpOpen:e=>{this.ensureLoaded().then(i=>i.events.onPopUpOpen(e));},onPdfOpen:e=>{this.ensureLoaded().then(i=>i.events.onPdfOpen(e));},onPdfClose:e=>{this.ensureLoaded().then(i=>i.events.onPdfClose(e));}}}get isOpen(){return this[t]?.isOpen??false}get isInitialized(){return this[t]?.isInitialized??false}async init(e){return (await this.ensureLoaded()).init(e)}destroy(){this[t]&&this[t].destroy();}getVersion(){return this[t]?.getVersion()??"Not initialized"}async initChat(e){return (await this.ensureLoaded()).initChat(e)}async postChatInfo(e){return (await this.ensureLoaded()).postChatInfo(e)}async getTimelineInfo(e){return (await this.ensureLoaded()).getTimelineInfo(e)}},h=p;
|
|
2
|
+
module.exports=h;//# sourceMappingURL=index.js.map
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../index.ts"],"names":["CDN_LOADER_URL","loadCDNLoader","loadingPromise","resolve","reject","script","checkSDK","existingScript","TapSDK","config","__publicField","params","sdk","callback","handler","index_default"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * TapSDK - npm package wrapper\n *\n * Simply loads the CDN loader which handles version management and SDK loading.\n * This keeps the npm package minimal and allows instant updates via CDN.\n */\n\nimport type {\n TapSDKConfig,\n TapSDKInitParams,\n Course,\n ContainerStyle,\n PositionType,\n SeekTimelineParamsType,\n AlarmMessageInstanceType,\n AlarmType,\n} from './types';\n\nconst CDN_LOADER_URL = 'https://files.edutap.ai/tap-sdk/loader.js';\n\n// Global namespace for loaded SDK\n// Export type for IIFE bundles loaded via window.TapSDK\nexport type TapSDKConstructor = new (config: TapSDKConfig) => TapSDKInstance;\n\ndeclare global {\n interface Window {\n TapSDK?: TapSDKConstructor;\n __TAP_SDK_LOADER_LOADED__?: boolean;\n __TAP_SDK_LOADER_LOADING__?: Promise<void>;\n }\n}\n\ninterface TapSDKInstance {\n events: {\n seekTimeline: (params: SeekTimelineParamsType) => void;\n onTimelineSeek: (callback: (clipPlayHead: number, clipId: string) => void) => void;\n onChatInitiated: (handler: () => void) => void;\n onChatOpened: (handler: () => void) => void;\n onChatClosed: (handler: () => void) => void;\n onAlarmFadeIn: (handler: (messageInfo: AlarmMessageInstanceType) => void) => void;\n onPopUpOpen: (handler: (popUpInfo: any) => void) => void;\n onPdfOpen: (handler: () => void) => void;\n onPdfClose: (handler: () => void) => void;\n };\n isOpen: boolean;\n isInitialized: boolean;\n init(params: TapSDKInitParams): Promise<void>;\n destroy(): void;\n getVersion(): string;\n // Deprecated methods\n initChat(params: TapSDKInitParams): Promise<void>;\n postChatInfo(params: { clipId: string; clipPlayHead: number }): Promise<void>;\n getTimelineInfo(params: { callback: (clipPlayHead: number, clipId: string) => void }): Promise<void>;\n}\n\n/**\n * Loads the CDN loader script\n * The loader will then fetch versions.json and load the appropriate SDK version\n */\nfunction loadCDNLoader(): Promise<void> {\n // If already loaded, return immediately\n if (window.__TAP_SDK_LOADER_LOADED__ && window.TapSDK) {\n return Promise.resolve();\n }\n\n // If currently loading, return the existing promise\n if (window.__TAP_SDK_LOADER_LOADING__) {\n return window.__TAP_SDK_LOADER_LOADING__;\n }\n\n // Create loading promise\n const loadingPromise = new Promise<void>((resolve, reject) => {\n if (typeof document === 'undefined') {\n reject(new Error('TapSDK requires browser environment (document is undefined)'));\n return;\n }\n\n const script = document.createElement('script');\n script.src = CDN_LOADER_URL;\n script.async = true;\n\n script.onload = () => {\n // The loader script will load the actual SDK\n // We need to wait a bit for the loader to fetch and load the SDK\n const checkSDK = () => {\n if (window.TapSDK) {\n window.__TAP_SDK_LOADER_LOADED__ = true;\n window.__TAP_SDK_LOADER_LOADING__ = undefined;\n resolve();\n } else {\n // Check again after a short delay\n setTimeout(checkSDK, 50);\n }\n };\n checkSDK();\n };\n\n script.onerror = () => {\n window.__TAP_SDK_LOADER_LOADING__ = undefined;\n reject(new Error(`Failed to load TapSDK CDN loader: ${CDN_LOADER_URL}`));\n };\n\n // Check if script already exists\n const existingScript = document.querySelector(`script[src=\"${CDN_LOADER_URL}\"]`);\n if (existingScript) {\n // Script already added but not yet loaded\n existingScript.addEventListener('load', () => {\n const checkSDK = () => {\n if (window.TapSDK) resolve();\n else setTimeout(checkSDK, 50);\n };\n checkSDK();\n });\n existingScript.addEventListener('error', () =>\n reject(new Error(`Failed to load TapSDK CDN loader: ${CDN_LOADER_URL}`))\n );\n } else {\n document.head.appendChild(script);\n }\n });\n\n window.__TAP_SDK_LOADER_LOADING__ = loadingPromise;\n return loadingPromise;\n}\n\n/**\n * TapSDK Wrapper Class\n *\n * Loads the CDN loader and proxies all calls to the actual SDK\n */\nclass TapSDK implements TapSDKInstance {\n private config: TapSDKConfig;\n private sdkInstance?: TapSDKInstance;\n private loadPromise: Promise<void>;\n\n constructor(config: TapSDKConfig) {\n this.config = config;\n this.loadPromise = this.loadAndInitialize();\n }\n\n private async loadAndInitialize(): Promise<void> {\n await loadCDNLoader();\n\n if (!window.TapSDK) {\n throw new Error('TapSDK not available after loading CDN loader');\n }\n\n this.sdkInstance = new window.TapSDK(this.config);\n }\n\n private async ensureLoaded(): Promise<TapSDKInstance> {\n await this.loadPromise;\n if (!this.sdkInstance) {\n throw new Error('TapSDK instance not initialized');\n }\n return this.sdkInstance;\n }\n\n // Public API - all methods proxy to the loaded SDK\n get events() {\n return {\n seekTimeline: (params: SeekTimelineParamsType) => {\n this.ensureLoaded().then(sdk => sdk.events.seekTimeline(params));\n },\n onTimelineSeek: (callback: (clipPlayHead: number, clipId: string) => void) => {\n this.ensureLoaded().then(sdk => sdk.events.onTimelineSeek(callback));\n },\n onChatInitiated: (handler: () => void) => {\n this.ensureLoaded().then(sdk => sdk.events.onChatInitiated(handler));\n },\n onChatOpened: (handler: () => void) => {\n this.ensureLoaded().then(sdk => sdk.events.onChatOpened(handler));\n },\n onChatClosed: (handler: () => void) => {\n this.ensureLoaded().then(sdk => sdk.events.onChatClosed(handler));\n },\n onAlarmFadeIn: (handler: (messageInfo: AlarmMessageInstanceType) => void) => {\n this.ensureLoaded().then(sdk => sdk.events.onAlarmFadeIn(handler));\n },\n onPopUpOpen: (handler: (popUpInfo: any) => void) => {\n this.ensureLoaded().then(sdk => sdk.events.onPopUpOpen(handler));\n },\n onPdfOpen: (handler: () => void) => {\n this.ensureLoaded().then(sdk => sdk.events.onPdfOpen(handler));\n },\n onPdfClose: (handler: () => void) => {\n this.ensureLoaded().then(sdk => sdk.events.onPdfClose(handler));\n },\n };\n }\n\n get isOpen(): boolean {\n return this.sdkInstance?.isOpen ?? false;\n }\n\n get isInitialized(): boolean {\n return this.sdkInstance?.isInitialized ?? false;\n }\n\n async init(params: TapSDKInitParams): Promise<void> {\n const sdk = await this.ensureLoaded();\n return sdk.init(params);\n }\n\n destroy(): void {\n if (this.sdkInstance) {\n this.sdkInstance.destroy();\n }\n }\n\n getVersion(): string {\n return this.sdkInstance?.getVersion() ?? 'Not initialized';\n }\n\n // Deprecated methods\n async initChat(params: TapSDKInitParams): Promise<void> {\n const sdk = await this.ensureLoaded();\n return sdk.initChat(params);\n }\n\n async postChatInfo(params: { clipId: string; clipPlayHead: number }): Promise<void> {\n const sdk = await this.ensureLoaded();\n return sdk.postChatInfo(params);\n }\n\n async getTimelineInfo(params: { callback: (clipPlayHead: number, clipId: string) => void }): Promise<void> {\n const sdk = await this.ensureLoaded();\n return sdk.getTimelineInfo(params);\n }\n}\n\n// Export the SDK class as default (for: import TapSDK from '@coxwave/tap-sdk')\nexport default TapSDK;\n\n// Export TapSDK instance type (for: import type { TapSDK } from '@coxwave/tap-sdk')\nexport type { TapSDKInstance as TapSDK };\n\n// Keep TapSDKInstance for backward compatibility\nexport type { TapSDKInstance };\n\n// Re-export types for API compatibility\nexport type {\n TapSDKConfig,\n TapSDKInitParams,\n Course,\n ContainerStyle,\n PositionType,\n SeekTimelineParamsType,\n AlarmMessageInstanceType,\n AlarmType,\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../index.ts"],"names":["CDN_LOADER_URL","loadCDNLoader","loadingPromise","resolve","reject","script","checkSDK","existingScript","SDK_INSTANCE","SDK_INSTANCE_LOADING","_a","_b","TapKit","config","__publicField","sdk","params","callback","handler","index_default"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * TapKit wrapper - npm package wrapper\n *\n * Simply loads the CDN loader which handles version management and SDK loading.\n * This keeps the npm package minimal and allows instant updates via CDN.\n *\n * Demo version: Automatically configures localStorage for demo environment.\n */\n\n// Configure demo environment if this is the demo version\nif (typeof localStorage !== \"undefined\") {\n // Demo edutap FE URL\n localStorage.setItem(\n \"tap-url-storage\",\n JSON.stringify({\n state: { tapUrl: \"https://demo-edutap.vercel.app\" },\n })\n );\n\n // Demo API URL\n localStorage.setItem(\n \"tap-api-url-storage\",\n JSON.stringify({\n state: { apiUrl: \"https://tapadminstaging.coxwave.link\" },\n })\n );\n\n // Demo environment flag (enables console logging)\n localStorage.setItem(\"tap-environment\", \"demo\");\n\n console.log(\"[TapSDK Demo] Environment configured:\", {\n tapUrl: \"https://demo-edutap.vercel.app\",\n apiUrl: \"https://tapadminstaging.coxwave.link\",\n environment: \"demo\",\n });\n}\n\nimport type {\n TapKitConfig,\n TapKitInitParams,\n Course,\n ContainerStyle,\n PositionType,\n SeekTimelineParamsType,\n AlarmMessageInstanceType,\n AlarmType,\n} from \"./types\";\n\nconst CDN_LOADER_URL = \"https://files.edutap.ai/tap-sdk/loader.js\";\n\n// Global namespace for loaded SDK\n// Export type for IIFE bundles loaded via window.TapKit\nexport type TapKitConstructor = new (config: TapKitConfig) => TapKitInstance;\n\ndeclare global {\n interface Window {\n TapKit?: TapKitConstructor;\n __TAP_KIT_LOADER_LOADED__?: boolean;\n __TAP_KIT_LOADER_LOADING__?: Promise<void>;\n }\n}\n\ninterface TapKitInstance {\n events: {\n seekTimeline: (params: SeekTimelineParamsType) => void;\n onTimelineSeek: (\n callback: (clipPlayHead: number, clipId: string) => void\n ) => void;\n onChatInitiated: (handler: () => void) => void;\n onChatOpened: (handler: () => void) => void;\n onChatClosed: (handler: () => void) => void;\n onAlarmFadeIn: (\n handler: (messageInfo: AlarmMessageInstanceType) => void\n ) => void;\n onPopUpOpen: (handler: (popUpInfo: any) => void) => void;\n onPdfOpen: (handler: () => void) => void;\n onPdfClose: (handler: () => void) => void;\n };\n isOpen: boolean;\n isInitialized: boolean;\n readyPromise: Promise<void>;\n init(params: TapKitInitParams): Promise<void>;\n destroy(): void;\n getVersion(): string;\n // Deprecated methods\n initChat(params: TapKitInitParams): Promise<void>;\n postChatInfo(params: { clipId: string; clipPlayHead: number }): Promise<void>;\n getTimelineInfo(params: {\n callback: (clipPlayHead: number, clipId: string) => void;\n }): Promise<void>;\n}\n\n/**\n * Loads the CDN loader script\n * The loader will then fetch versions.json and load the appropriate SDK version\n */\nfunction loadCDNLoader(): Promise<void> {\n // If already loaded, return immediately\n if (window.__TAP_KIT_LOADER_LOADED__ && window.TapKit) {\n return Promise.resolve();\n }\n\n // If currently loading, return the existing promise\n if (window.__TAP_KIT_LOADER_LOADING__) {\n return window.__TAP_KIT_LOADER_LOADING__;\n }\n\n // Create loading promise\n const loadingPromise = new Promise<void>((resolve, reject) => {\n if (typeof document === \"undefined\") {\n reject(\n new Error(\"TapKit requires browser environment (document is undefined)\")\n );\n return;\n }\n\n const script = document.createElement(\"script\");\n script.src = CDN_LOADER_URL;\n script.async = true;\n\n script.onload = () => {\n // The loader script will load the actual SDK\n // We need to wait a bit for the loader to fetch and load the SDK\n const checkSDK = () => {\n if (window.TapKit) {\n window.__TAP_KIT_LOADER_LOADED__ = true;\n window.__TAP_KIT_LOADER_LOADING__ = undefined;\n resolve();\n } else {\n // Check again after a short delay\n setTimeout(checkSDK, 50);\n }\n };\n checkSDK();\n };\n\n script.onerror = () => {\n window.__TAP_KIT_LOADER_LOADING__ = undefined;\n reject(new Error(`Failed to load TapKit CDN loader: ${CDN_LOADER_URL}`));\n };\n\n // Check if script already exists\n const existingScript = document.querySelector(\n `script[src=\"${CDN_LOADER_URL}\"]`\n );\n if (existingScript) {\n // Script already added but not yet loaded\n existingScript.addEventListener(\"load\", () => {\n const checkSDK = () => {\n if (window.TapKit) resolve();\n else setTimeout(checkSDK, 50);\n };\n checkSDK();\n });\n existingScript.addEventListener(\"error\", () =>\n reject(new Error(`Failed to load TapKit CDN loader: ${CDN_LOADER_URL}`))\n );\n } else {\n document.head.appendChild(script);\n }\n });\n\n window.__TAP_KIT_LOADER_LOADING__ = loadingPromise;\n return loadingPromise;\n}\n\n// Use Symbol to hide SDK instance from enumeration\nconst SDK_INSTANCE = Symbol(\"sdkInstance\");\nconst SDK_INSTANCE_LOADING = Symbol(\"sdkInstanceLoading\");\n\n/**\n * TapKit Wrapper Class\n *\n * Loads the CDN loader and proxies all calls to the actual SDK\n */\nclass TapKit implements TapKitInstance {\n private [SDK_INSTANCE]?: TapKitInstance;\n private [SDK_INSTANCE_LOADING]: Promise<void>;\n\n constructor(config: TapKitConfig) {\n this[SDK_INSTANCE_LOADING] = this.loadAndInitialize(config);\n }\n\n private async loadAndInitialize(config: TapKitConfig): Promise<void> {\n console.log(\"[tap-sdk] Loading CDN loader...\");\n await loadCDNLoader();\n console.log(\"[tap-sdk] CDN loader loaded, window.TapKit:\", !!window.TapKit);\n\n if (!window.TapKit) {\n throw new Error(\"TapKit not available after loading CDN loader\");\n }\n\n console.log(\"[tap-sdk] Creating TapKit instance...\");\n this[SDK_INSTANCE] = new window.TapKit(config);\n console.log(\"[tap-sdk] TapKit instance created\");\n }\n\n private async ensureLoaded(): Promise<TapKitInstance> {\n console.log(\"[tap-sdk] ensureLoaded: waiting for SDK_INSTANCE_LOADING...\");\n await this[SDK_INSTANCE_LOADING]; // Wait for SDK instance to be created\n console.log(\"[tap-sdk] ensureLoaded: SDK_INSTANCE_LOADING completed\");\n\n if (!this[SDK_INSTANCE]) {\n throw new Error(\"TapKit instance not initialized\");\n }\n\n console.log(\"[tap-sdk] ensureLoaded: returning SDK instance\");\n return this[SDK_INSTANCE];\n }\n\n // Expose tap-kit-core's readyPromise for advanced users\n // This resolves after init() is called and tap-kit-core is fully initialized\n get readyPromise(): Promise<void> {\n return this.ensureLoaded().then((sdk) => sdk.readyPromise);\n }\n\n // Public API - all methods proxy to the loaded SDK\n get events() {\n return {\n seekTimeline: (params: SeekTimelineParamsType) => {\n this.ensureLoaded().then((sdk) => sdk.events.seekTimeline(params));\n },\n onTimelineSeek: (\n callback: (clipPlayHead: number, clipId: string) => void\n ) => {\n this.ensureLoaded().then((sdk) => sdk.events.onTimelineSeek(callback));\n },\n onChatInitiated: (handler: () => void) => {\n this.ensureLoaded().then((sdk) => sdk.events.onChatInitiated(handler));\n },\n onChatOpened: (handler: () => void) => {\n this.ensureLoaded().then((sdk) => sdk.events.onChatOpened(handler));\n },\n onChatClosed: (handler: () => void) => {\n this.ensureLoaded().then((sdk) => sdk.events.onChatClosed(handler));\n },\n onAlarmFadeIn: (\n handler: (messageInfo: AlarmMessageInstanceType) => void\n ) => {\n this.ensureLoaded().then((sdk) => sdk.events.onAlarmFadeIn(handler));\n },\n onPopUpOpen: (handler: (popUpInfo: any) => void) => {\n this.ensureLoaded().then((sdk) => sdk.events.onPopUpOpen(handler));\n },\n onPdfOpen: (handler: () => void) => {\n this.ensureLoaded().then((sdk) => sdk.events.onPdfOpen(handler));\n },\n onPdfClose: (handler: () => void) => {\n this.ensureLoaded().then((sdk) => sdk.events.onPdfClose(handler));\n },\n };\n }\n\n get isOpen(): boolean {\n return this[SDK_INSTANCE]?.isOpen ?? false;\n }\n\n get isInitialized(): boolean {\n return this[SDK_INSTANCE]?.isInitialized ?? false;\n }\n\n async init(params: TapKitInitParams): Promise<void> {\n const sdk = await this.ensureLoaded();\n return sdk.init(params);\n }\n\n destroy(): void {\n if (this[SDK_INSTANCE]) {\n this[SDK_INSTANCE].destroy();\n }\n }\n\n getVersion(): string {\n return this[SDK_INSTANCE]?.getVersion() ?? \"Not initialized\";\n }\n\n // Deprecated methods\n async initChat(params: TapKitInitParams): Promise<void> {\n const sdk = await this.ensureLoaded();\n return sdk.initChat(params);\n }\n\n async postChatInfo(params: {\n clipId: string;\n clipPlayHead: number;\n }): Promise<void> {\n const sdk = await this.ensureLoaded();\n return sdk.postChatInfo(params);\n }\n\n async getTimelineInfo(params: {\n callback: (clipPlayHead: number, clipId: string) => void;\n }): Promise<void> {\n const sdk = await this.ensureLoaded();\n return sdk.getTimelineInfo(params);\n }\n}\n\n// Export the SDK class as default (for: import TapKit from '@coxwave/tap-sdk')\nexport default TapKit;\n\n// Export TapKit instance type (for: import type { TapKit } from '@coxwave/tap-sdk')\nexport type { TapKitInstance as TapKit };\n\n// Re-export types for API compatibility\nexport type {\n TapKitConfig,\n TapKitInitParams,\n Course,\n ContainerStyle,\n PositionType,\n SeekTimelineParamsType,\n AlarmMessageInstanceType,\n AlarmType,\n};\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
2
|
-
export{
|
|
1
|
+
var T=Object.defineProperty;var _=(n,e,i)=>e in n?T(n,e,{enumerable:true,configurable:true,writable:true,value:i}):n[e]=i;var r=(n,e,i)=>_(n,typeof e!="symbol"?e+"":e,i);typeof localStorage<"u"&&(localStorage.setItem("tap-url-storage",JSON.stringify({state:{tapUrl:"https://demo-edutap.vercel.app"}})),localStorage.setItem("tap-api-url-storage",JSON.stringify({state:{apiUrl:"https://tapadminstaging.coxwave.link"}})),localStorage.setItem("tap-environment","demo"),console.log("[TapSDK Demo] Environment configured:",{tapUrl:"https://demo-edutap.vercel.app",apiUrl:"https://tapadminstaging.coxwave.link",environment:"demo"}));var s="https://files.edutap.ai/tap-sdk/loader.js";function v(){if(window.__TAP_KIT_LOADER_LOADED__&&window.TapKit)return Promise.resolve();if(window.__TAP_KIT_LOADER_LOADING__)return window.__TAP_KIT_LOADER_LOADING__;let n=new Promise((e,i)=>{if(typeof document>"u"){i(new Error("TapKit requires browser environment (document is undefined)"));return}let o=document.createElement("script");o.src=s,o.async=true,o.onload=()=>{let a=()=>{window.TapKit?(window.__TAP_KIT_LOADER_LOADED__=true,window.__TAP_KIT_LOADER_LOADING__=void 0,e()):setTimeout(a,50);};a();},o.onerror=()=>{window.__TAP_KIT_LOADER_LOADING__=void 0,i(new Error(`Failed to load TapKit CDN loader: ${s}`));};let d=document.querySelector(`script[src="${s}"]`);d?(d.addEventListener("load",()=>{let a=()=>{window.TapKit?e():setTimeout(a,50);};a();}),d.addEventListener("error",()=>i(new Error(`Failed to load TapKit CDN loader: ${s}`)))):document.head.appendChild(o);});return window.__TAP_KIT_LOADER_LOADING__=n,n}var t=Symbol("sdkInstance"),l=Symbol("sdkInstanceLoading"),c,m;m=t,c=l;var p=class{constructor(e){r(this,m);r(this,c);this[l]=this.loadAndInitialize(e);}async loadAndInitialize(e){if(console.log("[tap-sdk] Loading CDN loader..."),await v(),console.log("[tap-sdk] CDN loader loaded, window.TapKit:",!!window.TapKit),!window.TapKit)throw new Error("TapKit not available after loading CDN loader");console.log("[tap-sdk] Creating TapKit instance..."),this[t]=new window.TapKit(e),console.log("[tap-sdk] TapKit instance created");}async ensureLoaded(){if(console.log("[tap-sdk] ensureLoaded: waiting for SDK_INSTANCE_LOADING..."),await this[l],console.log("[tap-sdk] ensureLoaded: SDK_INSTANCE_LOADING completed"),!this[t])throw new Error("TapKit instance not initialized");return console.log("[tap-sdk] ensureLoaded: returning SDK instance"),this[t]}get readyPromise(){return this.ensureLoaded().then(e=>e.readyPromise)}get events(){return {seekTimeline:e=>{this.ensureLoaded().then(i=>i.events.seekTimeline(e));},onTimelineSeek:e=>{this.ensureLoaded().then(i=>i.events.onTimelineSeek(e));},onChatInitiated:e=>{this.ensureLoaded().then(i=>i.events.onChatInitiated(e));},onChatOpened:e=>{this.ensureLoaded().then(i=>i.events.onChatOpened(e));},onChatClosed:e=>{this.ensureLoaded().then(i=>i.events.onChatClosed(e));},onAlarmFadeIn:e=>{this.ensureLoaded().then(i=>i.events.onAlarmFadeIn(e));},onPopUpOpen:e=>{this.ensureLoaded().then(i=>i.events.onPopUpOpen(e));},onPdfOpen:e=>{this.ensureLoaded().then(i=>i.events.onPdfOpen(e));},onPdfClose:e=>{this.ensureLoaded().then(i=>i.events.onPdfClose(e));}}}get isOpen(){return this[t]?.isOpen??false}get isInitialized(){return this[t]?.isInitialized??false}async init(e){return (await this.ensureLoaded()).init(e)}destroy(){this[t]&&this[t].destroy();}getVersion(){return this[t]?.getVersion()??"Not initialized"}async initChat(e){return (await this.ensureLoaded()).initChat(e)}async postChatInfo(e){return (await this.ensureLoaded()).postChatInfo(e)}async getTimelineInfo(e){return (await this.ensureLoaded()).getTimelineInfo(e)}},h=p;
|
|
2
|
+
export{h as default};//# sourceMappingURL=index.mjs.map
|
|
3
3
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../index.ts"],"names":["CDN_LOADER_URL","loadCDNLoader","loadingPromise","resolve","reject","script","checkSDK","existingScript","TapSDK","config","__publicField","params","sdk","callback","handler","index_default"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * TapSDK - npm package wrapper\n *\n * Simply loads the CDN loader which handles version management and SDK loading.\n * This keeps the npm package minimal and allows instant updates via CDN.\n */\n\nimport type {\n TapSDKConfig,\n TapSDKInitParams,\n Course,\n ContainerStyle,\n PositionType,\n SeekTimelineParamsType,\n AlarmMessageInstanceType,\n AlarmType,\n} from './types';\n\nconst CDN_LOADER_URL = 'https://files.edutap.ai/tap-sdk/loader.js';\n\n// Global namespace for loaded SDK\n// Export type for IIFE bundles loaded via window.TapSDK\nexport type TapSDKConstructor = new (config: TapSDKConfig) => TapSDKInstance;\n\ndeclare global {\n interface Window {\n TapSDK?: TapSDKConstructor;\n __TAP_SDK_LOADER_LOADED__?: boolean;\n __TAP_SDK_LOADER_LOADING__?: Promise<void>;\n }\n}\n\ninterface TapSDKInstance {\n events: {\n seekTimeline: (params: SeekTimelineParamsType) => void;\n onTimelineSeek: (callback: (clipPlayHead: number, clipId: string) => void) => void;\n onChatInitiated: (handler: () => void) => void;\n onChatOpened: (handler: () => void) => void;\n onChatClosed: (handler: () => void) => void;\n onAlarmFadeIn: (handler: (messageInfo: AlarmMessageInstanceType) => void) => void;\n onPopUpOpen: (handler: (popUpInfo: any) => void) => void;\n onPdfOpen: (handler: () => void) => void;\n onPdfClose: (handler: () => void) => void;\n };\n isOpen: boolean;\n isInitialized: boolean;\n init(params: TapSDKInitParams): Promise<void>;\n destroy(): void;\n getVersion(): string;\n // Deprecated methods\n initChat(params: TapSDKInitParams): Promise<void>;\n postChatInfo(params: { clipId: string; clipPlayHead: number }): Promise<void>;\n getTimelineInfo(params: { callback: (clipPlayHead: number, clipId: string) => void }): Promise<void>;\n}\n\n/**\n * Loads the CDN loader script\n * The loader will then fetch versions.json and load the appropriate SDK version\n */\nfunction loadCDNLoader(): Promise<void> {\n // If already loaded, return immediately\n if (window.__TAP_SDK_LOADER_LOADED__ && window.TapSDK) {\n return Promise.resolve();\n }\n\n // If currently loading, return the existing promise\n if (window.__TAP_SDK_LOADER_LOADING__) {\n return window.__TAP_SDK_LOADER_LOADING__;\n }\n\n // Create loading promise\n const loadingPromise = new Promise<void>((resolve, reject) => {\n if (typeof document === 'undefined') {\n reject(new Error('TapSDK requires browser environment (document is undefined)'));\n return;\n }\n\n const script = document.createElement('script');\n script.src = CDN_LOADER_URL;\n script.async = true;\n\n script.onload = () => {\n // The loader script will load the actual SDK\n // We need to wait a bit for the loader to fetch and load the SDK\n const checkSDK = () => {\n if (window.TapSDK) {\n window.__TAP_SDK_LOADER_LOADED__ = true;\n window.__TAP_SDK_LOADER_LOADING__ = undefined;\n resolve();\n } else {\n // Check again after a short delay\n setTimeout(checkSDK, 50);\n }\n };\n checkSDK();\n };\n\n script.onerror = () => {\n window.__TAP_SDK_LOADER_LOADING__ = undefined;\n reject(new Error(`Failed to load TapSDK CDN loader: ${CDN_LOADER_URL}`));\n };\n\n // Check if script already exists\n const existingScript = document.querySelector(`script[src=\"${CDN_LOADER_URL}\"]`);\n if (existingScript) {\n // Script already added but not yet loaded\n existingScript.addEventListener('load', () => {\n const checkSDK = () => {\n if (window.TapSDK) resolve();\n else setTimeout(checkSDK, 50);\n };\n checkSDK();\n });\n existingScript.addEventListener('error', () =>\n reject(new Error(`Failed to load TapSDK CDN loader: ${CDN_LOADER_URL}`))\n );\n } else {\n document.head.appendChild(script);\n }\n });\n\n window.__TAP_SDK_LOADER_LOADING__ = loadingPromise;\n return loadingPromise;\n}\n\n/**\n * TapSDK Wrapper Class\n *\n * Loads the CDN loader and proxies all calls to the actual SDK\n */\nclass TapSDK implements TapSDKInstance {\n private config: TapSDKConfig;\n private sdkInstance?: TapSDKInstance;\n private loadPromise: Promise<void>;\n\n constructor(config: TapSDKConfig) {\n this.config = config;\n this.loadPromise = this.loadAndInitialize();\n }\n\n private async loadAndInitialize(): Promise<void> {\n await loadCDNLoader();\n\n if (!window.TapSDK) {\n throw new Error('TapSDK not available after loading CDN loader');\n }\n\n this.sdkInstance = new window.TapSDK(this.config);\n }\n\n private async ensureLoaded(): Promise<TapSDKInstance> {\n await this.loadPromise;\n if (!this.sdkInstance) {\n throw new Error('TapSDK instance not initialized');\n }\n return this.sdkInstance;\n }\n\n // Public API - all methods proxy to the loaded SDK\n get events() {\n return {\n seekTimeline: (params: SeekTimelineParamsType) => {\n this.ensureLoaded().then(sdk => sdk.events.seekTimeline(params));\n },\n onTimelineSeek: (callback: (clipPlayHead: number, clipId: string) => void) => {\n this.ensureLoaded().then(sdk => sdk.events.onTimelineSeek(callback));\n },\n onChatInitiated: (handler: () => void) => {\n this.ensureLoaded().then(sdk => sdk.events.onChatInitiated(handler));\n },\n onChatOpened: (handler: () => void) => {\n this.ensureLoaded().then(sdk => sdk.events.onChatOpened(handler));\n },\n onChatClosed: (handler: () => void) => {\n this.ensureLoaded().then(sdk => sdk.events.onChatClosed(handler));\n },\n onAlarmFadeIn: (handler: (messageInfo: AlarmMessageInstanceType) => void) => {\n this.ensureLoaded().then(sdk => sdk.events.onAlarmFadeIn(handler));\n },\n onPopUpOpen: (handler: (popUpInfo: any) => void) => {\n this.ensureLoaded().then(sdk => sdk.events.onPopUpOpen(handler));\n },\n onPdfOpen: (handler: () => void) => {\n this.ensureLoaded().then(sdk => sdk.events.onPdfOpen(handler));\n },\n onPdfClose: (handler: () => void) => {\n this.ensureLoaded().then(sdk => sdk.events.onPdfClose(handler));\n },\n };\n }\n\n get isOpen(): boolean {\n return this.sdkInstance?.isOpen ?? false;\n }\n\n get isInitialized(): boolean {\n return this.sdkInstance?.isInitialized ?? false;\n }\n\n async init(params: TapSDKInitParams): Promise<void> {\n const sdk = await this.ensureLoaded();\n return sdk.init(params);\n }\n\n destroy(): void {\n if (this.sdkInstance) {\n this.sdkInstance.destroy();\n }\n }\n\n getVersion(): string {\n return this.sdkInstance?.getVersion() ?? 'Not initialized';\n }\n\n // Deprecated methods\n async initChat(params: TapSDKInitParams): Promise<void> {\n const sdk = await this.ensureLoaded();\n return sdk.initChat(params);\n }\n\n async postChatInfo(params: { clipId: string; clipPlayHead: number }): Promise<void> {\n const sdk = await this.ensureLoaded();\n return sdk.postChatInfo(params);\n }\n\n async getTimelineInfo(params: { callback: (clipPlayHead: number, clipId: string) => void }): Promise<void> {\n const sdk = await this.ensureLoaded();\n return sdk.getTimelineInfo(params);\n }\n}\n\n// Export the SDK class as default (for: import TapSDK from '@coxwave/tap-sdk')\nexport default TapSDK;\n\n// Export TapSDK instance type (for: import type { TapSDK } from '@coxwave/tap-sdk')\nexport type { TapSDKInstance as TapSDK };\n\n// Keep TapSDKInstance for backward compatibility\nexport type { TapSDKInstance };\n\n// Re-export types for API compatibility\nexport type {\n TapSDKConfig,\n TapSDKInitParams,\n Course,\n ContainerStyle,\n PositionType,\n SeekTimelineParamsType,\n AlarmMessageInstanceType,\n AlarmType,\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../index.ts"],"names":["CDN_LOADER_URL","loadCDNLoader","loadingPromise","resolve","reject","script","checkSDK","existingScript","SDK_INSTANCE","SDK_INSTANCE_LOADING","_a","_b","TapKit","config","__publicField","sdk","params","callback","handler","index_default"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * TapKit wrapper - npm package wrapper\n *\n * Simply loads the CDN loader which handles version management and SDK loading.\n * This keeps the npm package minimal and allows instant updates via CDN.\n *\n * Demo version: Automatically configures localStorage for demo environment.\n */\n\n// Configure demo environment if this is the demo version\nif (typeof localStorage !== \"undefined\") {\n // Demo edutap FE URL\n localStorage.setItem(\n \"tap-url-storage\",\n JSON.stringify({\n state: { tapUrl: \"https://demo-edutap.vercel.app\" },\n })\n );\n\n // Demo API URL\n localStorage.setItem(\n \"tap-api-url-storage\",\n JSON.stringify({\n state: { apiUrl: \"https://tapadminstaging.coxwave.link\" },\n })\n );\n\n // Demo environment flag (enables console logging)\n localStorage.setItem(\"tap-environment\", \"demo\");\n\n console.log(\"[TapSDK Demo] Environment configured:\", {\n tapUrl: \"https://demo-edutap.vercel.app\",\n apiUrl: \"https://tapadminstaging.coxwave.link\",\n environment: \"demo\",\n });\n}\n\nimport type {\n TapKitConfig,\n TapKitInitParams,\n Course,\n ContainerStyle,\n PositionType,\n SeekTimelineParamsType,\n AlarmMessageInstanceType,\n AlarmType,\n} from \"./types\";\n\nconst CDN_LOADER_URL = \"https://files.edutap.ai/tap-sdk/loader.js\";\n\n// Global namespace for loaded SDK\n// Export type for IIFE bundles loaded via window.TapKit\nexport type TapKitConstructor = new (config: TapKitConfig) => TapKitInstance;\n\ndeclare global {\n interface Window {\n TapKit?: TapKitConstructor;\n __TAP_KIT_LOADER_LOADED__?: boolean;\n __TAP_KIT_LOADER_LOADING__?: Promise<void>;\n }\n}\n\ninterface TapKitInstance {\n events: {\n seekTimeline: (params: SeekTimelineParamsType) => void;\n onTimelineSeek: (\n callback: (clipPlayHead: number, clipId: string) => void\n ) => void;\n onChatInitiated: (handler: () => void) => void;\n onChatOpened: (handler: () => void) => void;\n onChatClosed: (handler: () => void) => void;\n onAlarmFadeIn: (\n handler: (messageInfo: AlarmMessageInstanceType) => void\n ) => void;\n onPopUpOpen: (handler: (popUpInfo: any) => void) => void;\n onPdfOpen: (handler: () => void) => void;\n onPdfClose: (handler: () => void) => void;\n };\n isOpen: boolean;\n isInitialized: boolean;\n readyPromise: Promise<void>;\n init(params: TapKitInitParams): Promise<void>;\n destroy(): void;\n getVersion(): string;\n // Deprecated methods\n initChat(params: TapKitInitParams): Promise<void>;\n postChatInfo(params: { clipId: string; clipPlayHead: number }): Promise<void>;\n getTimelineInfo(params: {\n callback: (clipPlayHead: number, clipId: string) => void;\n }): Promise<void>;\n}\n\n/**\n * Loads the CDN loader script\n * The loader will then fetch versions.json and load the appropriate SDK version\n */\nfunction loadCDNLoader(): Promise<void> {\n // If already loaded, return immediately\n if (window.__TAP_KIT_LOADER_LOADED__ && window.TapKit) {\n return Promise.resolve();\n }\n\n // If currently loading, return the existing promise\n if (window.__TAP_KIT_LOADER_LOADING__) {\n return window.__TAP_KIT_LOADER_LOADING__;\n }\n\n // Create loading promise\n const loadingPromise = new Promise<void>((resolve, reject) => {\n if (typeof document === \"undefined\") {\n reject(\n new Error(\"TapKit requires browser environment (document is undefined)\")\n );\n return;\n }\n\n const script = document.createElement(\"script\");\n script.src = CDN_LOADER_URL;\n script.async = true;\n\n script.onload = () => {\n // The loader script will load the actual SDK\n // We need to wait a bit for the loader to fetch and load the SDK\n const checkSDK = () => {\n if (window.TapKit) {\n window.__TAP_KIT_LOADER_LOADED__ = true;\n window.__TAP_KIT_LOADER_LOADING__ = undefined;\n resolve();\n } else {\n // Check again after a short delay\n setTimeout(checkSDK, 50);\n }\n };\n checkSDK();\n };\n\n script.onerror = () => {\n window.__TAP_KIT_LOADER_LOADING__ = undefined;\n reject(new Error(`Failed to load TapKit CDN loader: ${CDN_LOADER_URL}`));\n };\n\n // Check if script already exists\n const existingScript = document.querySelector(\n `script[src=\"${CDN_LOADER_URL}\"]`\n );\n if (existingScript) {\n // Script already added but not yet loaded\n existingScript.addEventListener(\"load\", () => {\n const checkSDK = () => {\n if (window.TapKit) resolve();\n else setTimeout(checkSDK, 50);\n };\n checkSDK();\n });\n existingScript.addEventListener(\"error\", () =>\n reject(new Error(`Failed to load TapKit CDN loader: ${CDN_LOADER_URL}`))\n );\n } else {\n document.head.appendChild(script);\n }\n });\n\n window.__TAP_KIT_LOADER_LOADING__ = loadingPromise;\n return loadingPromise;\n}\n\n// Use Symbol to hide SDK instance from enumeration\nconst SDK_INSTANCE = Symbol(\"sdkInstance\");\nconst SDK_INSTANCE_LOADING = Symbol(\"sdkInstanceLoading\");\n\n/**\n * TapKit Wrapper Class\n *\n * Loads the CDN loader and proxies all calls to the actual SDK\n */\nclass TapKit implements TapKitInstance {\n private [SDK_INSTANCE]?: TapKitInstance;\n private [SDK_INSTANCE_LOADING]: Promise<void>;\n\n constructor(config: TapKitConfig) {\n this[SDK_INSTANCE_LOADING] = this.loadAndInitialize(config);\n }\n\n private async loadAndInitialize(config: TapKitConfig): Promise<void> {\n console.log(\"[tap-sdk] Loading CDN loader...\");\n await loadCDNLoader();\n console.log(\"[tap-sdk] CDN loader loaded, window.TapKit:\", !!window.TapKit);\n\n if (!window.TapKit) {\n throw new Error(\"TapKit not available after loading CDN loader\");\n }\n\n console.log(\"[tap-sdk] Creating TapKit instance...\");\n this[SDK_INSTANCE] = new window.TapKit(config);\n console.log(\"[tap-sdk] TapKit instance created\");\n }\n\n private async ensureLoaded(): Promise<TapKitInstance> {\n console.log(\"[tap-sdk] ensureLoaded: waiting for SDK_INSTANCE_LOADING...\");\n await this[SDK_INSTANCE_LOADING]; // Wait for SDK instance to be created\n console.log(\"[tap-sdk] ensureLoaded: SDK_INSTANCE_LOADING completed\");\n\n if (!this[SDK_INSTANCE]) {\n throw new Error(\"TapKit instance not initialized\");\n }\n\n console.log(\"[tap-sdk] ensureLoaded: returning SDK instance\");\n return this[SDK_INSTANCE];\n }\n\n // Expose tap-kit-core's readyPromise for advanced users\n // This resolves after init() is called and tap-kit-core is fully initialized\n get readyPromise(): Promise<void> {\n return this.ensureLoaded().then((sdk) => sdk.readyPromise);\n }\n\n // Public API - all methods proxy to the loaded SDK\n get events() {\n return {\n seekTimeline: (params: SeekTimelineParamsType) => {\n this.ensureLoaded().then((sdk) => sdk.events.seekTimeline(params));\n },\n onTimelineSeek: (\n callback: (clipPlayHead: number, clipId: string) => void\n ) => {\n this.ensureLoaded().then((sdk) => sdk.events.onTimelineSeek(callback));\n },\n onChatInitiated: (handler: () => void) => {\n this.ensureLoaded().then((sdk) => sdk.events.onChatInitiated(handler));\n },\n onChatOpened: (handler: () => void) => {\n this.ensureLoaded().then((sdk) => sdk.events.onChatOpened(handler));\n },\n onChatClosed: (handler: () => void) => {\n this.ensureLoaded().then((sdk) => sdk.events.onChatClosed(handler));\n },\n onAlarmFadeIn: (\n handler: (messageInfo: AlarmMessageInstanceType) => void\n ) => {\n this.ensureLoaded().then((sdk) => sdk.events.onAlarmFadeIn(handler));\n },\n onPopUpOpen: (handler: (popUpInfo: any) => void) => {\n this.ensureLoaded().then((sdk) => sdk.events.onPopUpOpen(handler));\n },\n onPdfOpen: (handler: () => void) => {\n this.ensureLoaded().then((sdk) => sdk.events.onPdfOpen(handler));\n },\n onPdfClose: (handler: () => void) => {\n this.ensureLoaded().then((sdk) => sdk.events.onPdfClose(handler));\n },\n };\n }\n\n get isOpen(): boolean {\n return this[SDK_INSTANCE]?.isOpen ?? false;\n }\n\n get isInitialized(): boolean {\n return this[SDK_INSTANCE]?.isInitialized ?? false;\n }\n\n async init(params: TapKitInitParams): Promise<void> {\n const sdk = await this.ensureLoaded();\n return sdk.init(params);\n }\n\n destroy(): void {\n if (this[SDK_INSTANCE]) {\n this[SDK_INSTANCE].destroy();\n }\n }\n\n getVersion(): string {\n return this[SDK_INSTANCE]?.getVersion() ?? \"Not initialized\";\n }\n\n // Deprecated methods\n async initChat(params: TapKitInitParams): Promise<void> {\n const sdk = await this.ensureLoaded();\n return sdk.initChat(params);\n }\n\n async postChatInfo(params: {\n clipId: string;\n clipPlayHead: number;\n }): Promise<void> {\n const sdk = await this.ensureLoaded();\n return sdk.postChatInfo(params);\n }\n\n async getTimelineInfo(params: {\n callback: (clipPlayHead: number, clipId: string) => void;\n }): Promise<void> {\n const sdk = await this.ensureLoaded();\n return sdk.getTimelineInfo(params);\n }\n}\n\n// Export the SDK class as default (for: import TapKit from '@coxwave/tap-sdk')\nexport default TapKit;\n\n// Export TapKit instance type (for: import type { TapKit } from '@coxwave/tap-sdk')\nexport type { TapKitInstance as TapKit };\n\n// Re-export types for API compatibility\nexport type {\n TapKitConfig,\n TapKitInitParams,\n Course,\n ContainerStyle,\n PositionType,\n SeekTimelineParamsType,\n AlarmMessageInstanceType,\n AlarmType,\n};\n"]}
|
package/index.ts
CHANGED
|
@@ -1,56 +1,93 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* TapKit wrapper - npm package wrapper
|
|
3
3
|
*
|
|
4
4
|
* Simply loads the CDN loader which handles version management and SDK loading.
|
|
5
5
|
* This keeps the npm package minimal and allows instant updates via CDN.
|
|
6
|
+
*
|
|
7
|
+
* Demo version: Automatically configures localStorage for demo environment.
|
|
6
8
|
*/
|
|
7
9
|
|
|
10
|
+
// Configure demo environment if this is the demo version
|
|
11
|
+
if (typeof localStorage !== "undefined") {
|
|
12
|
+
// Demo edutap FE URL
|
|
13
|
+
localStorage.setItem(
|
|
14
|
+
"tap-url-storage",
|
|
15
|
+
JSON.stringify({
|
|
16
|
+
state: { tapUrl: "https://demo-edutap.vercel.app" },
|
|
17
|
+
})
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
// Demo API URL
|
|
21
|
+
localStorage.setItem(
|
|
22
|
+
"tap-api-url-storage",
|
|
23
|
+
JSON.stringify({
|
|
24
|
+
state: { apiUrl: "https://tapadminstaging.coxwave.link" },
|
|
25
|
+
})
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
// Demo environment flag (enables console logging)
|
|
29
|
+
localStorage.setItem("tap-environment", "demo");
|
|
30
|
+
|
|
31
|
+
console.log("[TapSDK Demo] Environment configured:", {
|
|
32
|
+
tapUrl: "https://demo-edutap.vercel.app",
|
|
33
|
+
apiUrl: "https://tapadminstaging.coxwave.link",
|
|
34
|
+
environment: "demo",
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
8
38
|
import type {
|
|
9
|
-
|
|
10
|
-
|
|
39
|
+
TapKitConfig,
|
|
40
|
+
TapKitInitParams,
|
|
11
41
|
Course,
|
|
12
42
|
ContainerStyle,
|
|
13
43
|
PositionType,
|
|
14
44
|
SeekTimelineParamsType,
|
|
15
45
|
AlarmMessageInstanceType,
|
|
16
46
|
AlarmType,
|
|
17
|
-
} from
|
|
47
|
+
} from "./types";
|
|
18
48
|
|
|
19
|
-
const CDN_LOADER_URL =
|
|
49
|
+
const CDN_LOADER_URL = "https://files.edutap.ai/tap-sdk/loader.js";
|
|
20
50
|
|
|
21
51
|
// Global namespace for loaded SDK
|
|
22
|
-
// Export type for IIFE bundles loaded via window.
|
|
23
|
-
export type
|
|
52
|
+
// Export type for IIFE bundles loaded via window.TapKit
|
|
53
|
+
export type TapKitConstructor = new (config: TapKitConfig) => TapKitInstance;
|
|
24
54
|
|
|
25
55
|
declare global {
|
|
26
56
|
interface Window {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
57
|
+
TapKit?: TapKitConstructor;
|
|
58
|
+
__TAP_KIT_LOADER_LOADED__?: boolean;
|
|
59
|
+
__TAP_KIT_LOADER_LOADING__?: Promise<void>;
|
|
30
60
|
}
|
|
31
61
|
}
|
|
32
62
|
|
|
33
|
-
interface
|
|
63
|
+
interface TapKitInstance {
|
|
34
64
|
events: {
|
|
35
65
|
seekTimeline: (params: SeekTimelineParamsType) => void;
|
|
36
|
-
onTimelineSeek: (
|
|
66
|
+
onTimelineSeek: (
|
|
67
|
+
callback: (clipPlayHead: number, clipId: string) => void
|
|
68
|
+
) => void;
|
|
37
69
|
onChatInitiated: (handler: () => void) => void;
|
|
38
70
|
onChatOpened: (handler: () => void) => void;
|
|
39
71
|
onChatClosed: (handler: () => void) => void;
|
|
40
|
-
onAlarmFadeIn: (
|
|
72
|
+
onAlarmFadeIn: (
|
|
73
|
+
handler: (messageInfo: AlarmMessageInstanceType) => void
|
|
74
|
+
) => void;
|
|
41
75
|
onPopUpOpen: (handler: (popUpInfo: any) => void) => void;
|
|
42
76
|
onPdfOpen: (handler: () => void) => void;
|
|
43
77
|
onPdfClose: (handler: () => void) => void;
|
|
44
78
|
};
|
|
45
79
|
isOpen: boolean;
|
|
46
80
|
isInitialized: boolean;
|
|
47
|
-
|
|
81
|
+
readyPromise: Promise<void>;
|
|
82
|
+
init(params: TapKitInitParams): Promise<void>;
|
|
48
83
|
destroy(): void;
|
|
49
84
|
getVersion(): string;
|
|
50
85
|
// Deprecated methods
|
|
51
|
-
initChat(params:
|
|
86
|
+
initChat(params: TapKitInitParams): Promise<void>;
|
|
52
87
|
postChatInfo(params: { clipId: string; clipPlayHead: number }): Promise<void>;
|
|
53
|
-
getTimelineInfo(params: {
|
|
88
|
+
getTimelineInfo(params: {
|
|
89
|
+
callback: (clipPlayHead: number, clipId: string) => void;
|
|
90
|
+
}): Promise<void>;
|
|
54
91
|
}
|
|
55
92
|
|
|
56
93
|
/**
|
|
@@ -59,23 +96,25 @@ interface TapSDKInstance {
|
|
|
59
96
|
*/
|
|
60
97
|
function loadCDNLoader(): Promise<void> {
|
|
61
98
|
// If already loaded, return immediately
|
|
62
|
-
if (window.
|
|
99
|
+
if (window.__TAP_KIT_LOADER_LOADED__ && window.TapKit) {
|
|
63
100
|
return Promise.resolve();
|
|
64
101
|
}
|
|
65
102
|
|
|
66
103
|
// If currently loading, return the existing promise
|
|
67
|
-
if (window.
|
|
68
|
-
return window.
|
|
104
|
+
if (window.__TAP_KIT_LOADER_LOADING__) {
|
|
105
|
+
return window.__TAP_KIT_LOADER_LOADING__;
|
|
69
106
|
}
|
|
70
107
|
|
|
71
108
|
// Create loading promise
|
|
72
109
|
const loadingPromise = new Promise<void>((resolve, reject) => {
|
|
73
|
-
if (typeof document ===
|
|
74
|
-
reject(
|
|
110
|
+
if (typeof document === "undefined") {
|
|
111
|
+
reject(
|
|
112
|
+
new Error("TapKit requires browser environment (document is undefined)")
|
|
113
|
+
);
|
|
75
114
|
return;
|
|
76
115
|
}
|
|
77
116
|
|
|
78
|
-
const script = document.createElement(
|
|
117
|
+
const script = document.createElement("script");
|
|
79
118
|
script.src = CDN_LOADER_URL;
|
|
80
119
|
script.async = true;
|
|
81
120
|
|
|
@@ -83,9 +122,9 @@ function loadCDNLoader(): Promise<void> {
|
|
|
83
122
|
// The loader script will load the actual SDK
|
|
84
123
|
// We need to wait a bit for the loader to fetch and load the SDK
|
|
85
124
|
const checkSDK = () => {
|
|
86
|
-
if (window.
|
|
87
|
-
window.
|
|
88
|
-
window.
|
|
125
|
+
if (window.TapKit) {
|
|
126
|
+
window.__TAP_KIT_LOADER_LOADED__ = true;
|
|
127
|
+
window.__TAP_KIT_LOADER_LOADING__ = undefined;
|
|
89
128
|
resolve();
|
|
90
129
|
} else {
|
|
91
130
|
// Check again after a short delay
|
|
@@ -96,152 +135,177 @@ function loadCDNLoader(): Promise<void> {
|
|
|
96
135
|
};
|
|
97
136
|
|
|
98
137
|
script.onerror = () => {
|
|
99
|
-
window.
|
|
100
|
-
reject(new Error(`Failed to load
|
|
138
|
+
window.__TAP_KIT_LOADER_LOADING__ = undefined;
|
|
139
|
+
reject(new Error(`Failed to load TapKit CDN loader: ${CDN_LOADER_URL}`));
|
|
101
140
|
};
|
|
102
141
|
|
|
103
142
|
// Check if script already exists
|
|
104
|
-
const existingScript = document.querySelector(
|
|
143
|
+
const existingScript = document.querySelector(
|
|
144
|
+
`script[src="${CDN_LOADER_URL}"]`
|
|
145
|
+
);
|
|
105
146
|
if (existingScript) {
|
|
106
147
|
// Script already added but not yet loaded
|
|
107
|
-
existingScript.addEventListener(
|
|
148
|
+
existingScript.addEventListener("load", () => {
|
|
108
149
|
const checkSDK = () => {
|
|
109
|
-
if (window.
|
|
150
|
+
if (window.TapKit) resolve();
|
|
110
151
|
else setTimeout(checkSDK, 50);
|
|
111
152
|
};
|
|
112
153
|
checkSDK();
|
|
113
154
|
});
|
|
114
|
-
existingScript.addEventListener(
|
|
115
|
-
reject(new Error(`Failed to load
|
|
155
|
+
existingScript.addEventListener("error", () =>
|
|
156
|
+
reject(new Error(`Failed to load TapKit CDN loader: ${CDN_LOADER_URL}`))
|
|
116
157
|
);
|
|
117
158
|
} else {
|
|
118
159
|
document.head.appendChild(script);
|
|
119
160
|
}
|
|
120
161
|
});
|
|
121
162
|
|
|
122
|
-
window.
|
|
163
|
+
window.__TAP_KIT_LOADER_LOADING__ = loadingPromise;
|
|
123
164
|
return loadingPromise;
|
|
124
165
|
}
|
|
125
166
|
|
|
167
|
+
// Use Symbol to hide SDK instance from enumeration
|
|
168
|
+
const SDK_INSTANCE = Symbol("sdkInstance");
|
|
169
|
+
const SDK_INSTANCE_LOADING = Symbol("sdkInstanceLoading");
|
|
170
|
+
|
|
126
171
|
/**
|
|
127
|
-
*
|
|
172
|
+
* TapKit Wrapper Class
|
|
128
173
|
*
|
|
129
174
|
* Loads the CDN loader and proxies all calls to the actual SDK
|
|
130
175
|
*/
|
|
131
|
-
class
|
|
132
|
-
private
|
|
133
|
-
private
|
|
134
|
-
private loadPromise: Promise<void>;
|
|
176
|
+
class TapKit implements TapKitInstance {
|
|
177
|
+
private [SDK_INSTANCE]?: TapKitInstance;
|
|
178
|
+
private [SDK_INSTANCE_LOADING]: Promise<void>;
|
|
135
179
|
|
|
136
|
-
constructor(config:
|
|
137
|
-
this
|
|
138
|
-
this.loadPromise = this.loadAndInitialize();
|
|
180
|
+
constructor(config: TapKitConfig) {
|
|
181
|
+
this[SDK_INSTANCE_LOADING] = this.loadAndInitialize(config);
|
|
139
182
|
}
|
|
140
183
|
|
|
141
|
-
private async loadAndInitialize(): Promise<void> {
|
|
184
|
+
private async loadAndInitialize(config: TapKitConfig): Promise<void> {
|
|
185
|
+
console.log("[tap-sdk] Loading CDN loader...");
|
|
142
186
|
await loadCDNLoader();
|
|
187
|
+
console.log("[tap-sdk] CDN loader loaded, window.TapKit:", !!window.TapKit);
|
|
143
188
|
|
|
144
|
-
if (!window.
|
|
145
|
-
throw new Error(
|
|
189
|
+
if (!window.TapKit) {
|
|
190
|
+
throw new Error("TapKit not available after loading CDN loader");
|
|
146
191
|
}
|
|
147
192
|
|
|
148
|
-
|
|
193
|
+
console.log("[tap-sdk] Creating TapKit instance...");
|
|
194
|
+
this[SDK_INSTANCE] = new window.TapKit(config);
|
|
195
|
+
console.log("[tap-sdk] TapKit instance created");
|
|
149
196
|
}
|
|
150
197
|
|
|
151
|
-
private async ensureLoaded(): Promise<
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
198
|
+
private async ensureLoaded(): Promise<TapKitInstance> {
|
|
199
|
+
console.log("[tap-sdk] ensureLoaded: waiting for SDK_INSTANCE_LOADING...");
|
|
200
|
+
await this[SDK_INSTANCE_LOADING]; // Wait for SDK instance to be created
|
|
201
|
+
console.log("[tap-sdk] ensureLoaded: SDK_INSTANCE_LOADING completed");
|
|
202
|
+
|
|
203
|
+
if (!this[SDK_INSTANCE]) {
|
|
204
|
+
throw new Error("TapKit instance not initialized");
|
|
155
205
|
}
|
|
156
|
-
|
|
206
|
+
|
|
207
|
+
console.log("[tap-sdk] ensureLoaded: returning SDK instance");
|
|
208
|
+
return this[SDK_INSTANCE];
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Expose tap-kit-core's readyPromise for advanced users
|
|
212
|
+
// This resolves after init() is called and tap-kit-core is fully initialized
|
|
213
|
+
get readyPromise(): Promise<void> {
|
|
214
|
+
return this.ensureLoaded().then((sdk) => sdk.readyPromise);
|
|
157
215
|
}
|
|
158
216
|
|
|
159
217
|
// Public API - all methods proxy to the loaded SDK
|
|
160
218
|
get events() {
|
|
161
219
|
return {
|
|
162
220
|
seekTimeline: (params: SeekTimelineParamsType) => {
|
|
163
|
-
this.ensureLoaded().then(sdk => sdk.events.seekTimeline(params));
|
|
221
|
+
this.ensureLoaded().then((sdk) => sdk.events.seekTimeline(params));
|
|
164
222
|
},
|
|
165
|
-
onTimelineSeek: (
|
|
166
|
-
|
|
223
|
+
onTimelineSeek: (
|
|
224
|
+
callback: (clipPlayHead: number, clipId: string) => void
|
|
225
|
+
) => {
|
|
226
|
+
this.ensureLoaded().then((sdk) => sdk.events.onTimelineSeek(callback));
|
|
167
227
|
},
|
|
168
228
|
onChatInitiated: (handler: () => void) => {
|
|
169
|
-
this.ensureLoaded().then(sdk => sdk.events.onChatInitiated(handler));
|
|
229
|
+
this.ensureLoaded().then((sdk) => sdk.events.onChatInitiated(handler));
|
|
170
230
|
},
|
|
171
231
|
onChatOpened: (handler: () => void) => {
|
|
172
|
-
this.ensureLoaded().then(sdk => sdk.events.onChatOpened(handler));
|
|
232
|
+
this.ensureLoaded().then((sdk) => sdk.events.onChatOpened(handler));
|
|
173
233
|
},
|
|
174
234
|
onChatClosed: (handler: () => void) => {
|
|
175
|
-
this.ensureLoaded().then(sdk => sdk.events.onChatClosed(handler));
|
|
235
|
+
this.ensureLoaded().then((sdk) => sdk.events.onChatClosed(handler));
|
|
176
236
|
},
|
|
177
|
-
onAlarmFadeIn: (
|
|
178
|
-
|
|
237
|
+
onAlarmFadeIn: (
|
|
238
|
+
handler: (messageInfo: AlarmMessageInstanceType) => void
|
|
239
|
+
) => {
|
|
240
|
+
this.ensureLoaded().then((sdk) => sdk.events.onAlarmFadeIn(handler));
|
|
179
241
|
},
|
|
180
242
|
onPopUpOpen: (handler: (popUpInfo: any) => void) => {
|
|
181
|
-
this.ensureLoaded().then(sdk => sdk.events.onPopUpOpen(handler));
|
|
243
|
+
this.ensureLoaded().then((sdk) => sdk.events.onPopUpOpen(handler));
|
|
182
244
|
},
|
|
183
245
|
onPdfOpen: (handler: () => void) => {
|
|
184
|
-
this.ensureLoaded().then(sdk => sdk.events.onPdfOpen(handler));
|
|
246
|
+
this.ensureLoaded().then((sdk) => sdk.events.onPdfOpen(handler));
|
|
185
247
|
},
|
|
186
248
|
onPdfClose: (handler: () => void) => {
|
|
187
|
-
this.ensureLoaded().then(sdk => sdk.events.onPdfClose(handler));
|
|
249
|
+
this.ensureLoaded().then((sdk) => sdk.events.onPdfClose(handler));
|
|
188
250
|
},
|
|
189
251
|
};
|
|
190
252
|
}
|
|
191
253
|
|
|
192
254
|
get isOpen(): boolean {
|
|
193
|
-
return this
|
|
255
|
+
return this[SDK_INSTANCE]?.isOpen ?? false;
|
|
194
256
|
}
|
|
195
257
|
|
|
196
258
|
get isInitialized(): boolean {
|
|
197
|
-
return this
|
|
259
|
+
return this[SDK_INSTANCE]?.isInitialized ?? false;
|
|
198
260
|
}
|
|
199
261
|
|
|
200
|
-
async init(params:
|
|
262
|
+
async init(params: TapKitInitParams): Promise<void> {
|
|
201
263
|
const sdk = await this.ensureLoaded();
|
|
202
264
|
return sdk.init(params);
|
|
203
265
|
}
|
|
204
266
|
|
|
205
267
|
destroy(): void {
|
|
206
|
-
if (this
|
|
207
|
-
this.
|
|
268
|
+
if (this[SDK_INSTANCE]) {
|
|
269
|
+
this[SDK_INSTANCE].destroy();
|
|
208
270
|
}
|
|
209
271
|
}
|
|
210
272
|
|
|
211
273
|
getVersion(): string {
|
|
212
|
-
return this
|
|
274
|
+
return this[SDK_INSTANCE]?.getVersion() ?? "Not initialized";
|
|
213
275
|
}
|
|
214
276
|
|
|
215
277
|
// Deprecated methods
|
|
216
|
-
async initChat(params:
|
|
278
|
+
async initChat(params: TapKitInitParams): Promise<void> {
|
|
217
279
|
const sdk = await this.ensureLoaded();
|
|
218
280
|
return sdk.initChat(params);
|
|
219
281
|
}
|
|
220
282
|
|
|
221
|
-
async postChatInfo(params: {
|
|
283
|
+
async postChatInfo(params: {
|
|
284
|
+
clipId: string;
|
|
285
|
+
clipPlayHead: number;
|
|
286
|
+
}): Promise<void> {
|
|
222
287
|
const sdk = await this.ensureLoaded();
|
|
223
288
|
return sdk.postChatInfo(params);
|
|
224
289
|
}
|
|
225
290
|
|
|
226
|
-
async getTimelineInfo(params: {
|
|
291
|
+
async getTimelineInfo(params: {
|
|
292
|
+
callback: (clipPlayHead: number, clipId: string) => void;
|
|
293
|
+
}): Promise<void> {
|
|
227
294
|
const sdk = await this.ensureLoaded();
|
|
228
295
|
return sdk.getTimelineInfo(params);
|
|
229
296
|
}
|
|
230
297
|
}
|
|
231
298
|
|
|
232
|
-
// Export the SDK class as default (for: import
|
|
233
|
-
export default
|
|
234
|
-
|
|
235
|
-
// Export TapSDK instance type (for: import type { TapSDK } from '@coxwave/tap-sdk')
|
|
236
|
-
export type { TapSDKInstance as TapSDK };
|
|
299
|
+
// Export the SDK class as default (for: import TapKit from '@coxwave/tap-sdk')
|
|
300
|
+
export default TapKit;
|
|
237
301
|
|
|
238
|
-
//
|
|
239
|
-
export type {
|
|
302
|
+
// Export TapKit instance type (for: import type { TapKit } from '@coxwave/tap-sdk')
|
|
303
|
+
export type { TapKitInstance as TapKit };
|
|
240
304
|
|
|
241
305
|
// Re-export types for API compatibility
|
|
242
306
|
export type {
|
|
243
|
-
|
|
244
|
-
|
|
307
|
+
TapKitConfig,
|
|
308
|
+
TapKitInitParams,
|
|
245
309
|
Course,
|
|
246
310
|
ContainerStyle,
|
|
247
311
|
PositionType,
|
package/package.json
CHANGED
package/types.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* TapKit Type Definitions
|
|
3
3
|
*
|
|
4
4
|
* Re-exported types for API compatibility with the loader.
|
|
5
|
-
* These types match the actual SDK implementation in tap-
|
|
5
|
+
* These types match the actual SDK implementation in tap-kit-core.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
// Re-export alarm types from tap-messages
|
|
@@ -12,12 +12,12 @@ export type {
|
|
|
12
12
|
} from '@coxwave/tap-messages';
|
|
13
13
|
|
|
14
14
|
// SDK Configuration
|
|
15
|
-
export type
|
|
15
|
+
export type TapKitConfig = {
|
|
16
16
|
apiKey: string;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
// SDK Initialization Parameters
|
|
20
|
-
export type
|
|
20
|
+
export type TapKitInitParams = {
|
|
21
21
|
buttonId: string;
|
|
22
22
|
course: Course;
|
|
23
23
|
container?: ContainerStyle;
|