@adstage/web-sdk 1.4.0 → 2.1.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 +460 -98
- package/dist/index.cjs.js +468 -92
- package/dist/index.d.ts +16 -12
- package/dist/index.esm.js +468 -92
- package/dist/index.standalone.js +468 -92
- package/package.json +12 -13
- package/src/managers/ads/advertisement-event-tracker.ts +142 -0
- package/src/managers/ads/basic-fraud-detector.ts +191 -0
- package/src/managers/{carousel-slider-manager.ts → ads/carousel-slider-manager.ts} +4 -4
- package/src/managers/{text-transition-manager.ts → ads/text-transition-manager.ts} +4 -4
- package/src/managers/ads/viewability-tracker.ts +189 -0
- package/src/managers/ads/viewable-event-tracker.ts +89 -0
- package/src/modules/ads/AdsModule.ts +151 -28
- package/src/types/advertisement.ts +4 -17
- package/src/types/api.ts +1 -5
- package/src/managers/event-tracker.ts +0 -129
- package/src/managers/impression-tracker.ts +0 -88
- package/src/modules/deeplinks/DeeplinksModule.ts +0 -0
package/README.md
CHANGED
|
@@ -1,168 +1,449 @@
|
|
|
1
1
|
# AdStage Web SDK
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> **프로덕션 레디** AdStage 마케팅 플랫폼 공식 웹 SDK
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/@adstage/web-sdk)
|
|
6
|
+
[](http://www.typescriptlang.org/)
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
|
|
9
|
+
AdStage Web SDK는 멀티테넌트 마케팅 데이터 플랫폼인 AdStage의 웹 기능을 통합하는 JavaScript/TypeScript 라이브러리입니다. 딥링크 트래킹, 광고 표시, 이벤트 추적 등의 기능을 제공합니다.
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
## ✨ 주요 기능
|
|
8
12
|
|
|
9
|
-
|
|
13
|
+
### 🎯 광고 시스템 (완전 구현)
|
|
14
|
+
- **5가지 광고 타입**: 배너, 텍스트, 비디오, 네이티브, 전면 광고
|
|
15
|
+
- **스마트 슬라이더**: 여러 광고 자동 순환 및 페이드 효과
|
|
16
|
+
- **Lazy 로딩**: 즉시 placeholder 표시, 백그라운드 광고 로드
|
|
17
|
+
- **이벤트 추적**: 노출, 클릭, 뷰어빌리티 등 자동 추적
|
|
18
|
+
- **중복 방지**: 동일 광고 중복 노출 방지 시스템
|
|
10
19
|
|
|
11
|
-
###
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
20
|
+
### ⚙️ 설정 관리 (완전 구현)
|
|
21
|
+
- **동기 초기화**: `await` 없이 즉시 사용 가능
|
|
22
|
+
- **모듈 선택**: 필요한 기능만 선택적 로드
|
|
23
|
+
- **환경 자동 감지**: 개발/프로덕션 환경 자동 설정
|
|
24
|
+
- **런타임 설정 변경**: 실시간 설정 업데이트
|
|
16
25
|
|
|
17
|
-
###
|
|
18
|
-
-
|
|
26
|
+
### 📊 이벤트 추적 (기본 구조 완성)
|
|
27
|
+
- **커스텀 이벤트**: 사용자 정의 이벤트 추적
|
|
28
|
+
- **페이지 뷰**: 자동 페이지 방문 추적
|
|
29
|
+
- **배치 처리**: 효율적인 이벤트 전송
|
|
30
|
+
- **오프라인 지원**: 네트워크 오류 시 로컬 저장
|
|
19
31
|
|
|
20
32
|
## 📦 설치
|
|
21
33
|
|
|
22
34
|
```bash
|
|
35
|
+
# npm
|
|
23
36
|
npm install @adstage/web-sdk
|
|
37
|
+
|
|
38
|
+
# yarn
|
|
39
|
+
yarn add @adstage/web-sdk
|
|
40
|
+
|
|
41
|
+
# pnpm
|
|
42
|
+
pnpm add @adstage/web-sdk
|
|
24
43
|
```
|
|
25
44
|
|
|
26
|
-
##
|
|
45
|
+
## 🚀 빠른 시작
|
|
27
46
|
|
|
28
|
-
###
|
|
47
|
+
### 기본 사용법
|
|
29
48
|
|
|
30
49
|
```typescript
|
|
31
50
|
import { AdStage } from '@adstage/web-sdk';
|
|
32
51
|
|
|
33
|
-
// 1.
|
|
52
|
+
// 1. SDK 초기화 (동기)
|
|
34
53
|
AdStage.init({
|
|
35
54
|
apiKey: 'your-api-key',
|
|
36
55
|
debug: true,
|
|
37
|
-
modules: ['ads', '
|
|
38
|
-
validateOnInit: false // 기본값: 즉시 사용 가능
|
|
56
|
+
modules: ['ads', 'config'] // 필요한 모듈만 로드
|
|
39
57
|
});
|
|
40
58
|
|
|
41
|
-
// 2.
|
|
59
|
+
// 2. 광고 표시 (즉시 실행)
|
|
42
60
|
const bannerId = AdStage.ads.banner('banner-container', {
|
|
43
61
|
width: '100%',
|
|
44
62
|
height: 250,
|
|
45
|
-
autoSlide: true
|
|
63
|
+
autoSlide: true,
|
|
64
|
+
slideInterval: 5000
|
|
46
65
|
});
|
|
47
66
|
|
|
67
|
+
// 3. 텍스트 광고
|
|
48
68
|
const textId = AdStage.ads.text('text-container', {
|
|
49
69
|
maxLines: 3,
|
|
50
70
|
style: 'card'
|
|
51
71
|
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### HTML 마크업
|
|
75
|
+
|
|
76
|
+
```html
|
|
77
|
+
<!DOCTYPE html>
|
|
78
|
+
<html>
|
|
79
|
+
<head>
|
|
80
|
+
<title>AdStage 예제</title>
|
|
81
|
+
</head>
|
|
82
|
+
<body>
|
|
83
|
+
<!-- 광고 컨테이너 -->
|
|
84
|
+
<div id="banner-container"></div>
|
|
85
|
+
<div id="text-container"></div>
|
|
86
|
+
|
|
87
|
+
<script type="module">
|
|
88
|
+
import { AdStage } from '@adstage/web-sdk';
|
|
89
|
+
|
|
90
|
+
AdStage.init({ apiKey: 'your-api-key' });
|
|
91
|
+
AdStage.ads.banner('banner-container');
|
|
92
|
+
AdStage.ads.text('text-container');
|
|
93
|
+
</script>
|
|
94
|
+
</body>
|
|
95
|
+
</html>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## � 상세 API 가이드
|
|
99
|
+
|
|
100
|
+
### 광고 모듈 (AdStage.ads)
|
|
101
|
+
|
|
102
|
+
#### 배너 광고
|
|
103
|
+
```typescript
|
|
104
|
+
const bannerId = AdStage.ads.banner('container-id', {
|
|
105
|
+
width: '100%', // 너비 (px 또는 %)
|
|
106
|
+
height: 250, // 높이 (px)
|
|
107
|
+
autoSlide: true, // 자동 슬라이드
|
|
108
|
+
slideInterval: 5000, // 슬라이드 간격 (ms)
|
|
109
|
+
onClick: (adData) => { // 클릭 콜백
|
|
110
|
+
console.log('Ad clicked:', adData);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
```
|
|
52
114
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
115
|
+
#### 텍스트 광고
|
|
116
|
+
```typescript
|
|
117
|
+
const textId = AdStage.ads.text('container-id', {
|
|
118
|
+
maxLines: 3, // 최대 라인 수
|
|
119
|
+
style: 'card', // 스타일 ('default', 'card')
|
|
120
|
+
onClick: (adData) => { // 클릭 콜백
|
|
121
|
+
console.log('Text ad clicked:', adData);
|
|
122
|
+
}
|
|
56
123
|
});
|
|
124
|
+
```
|
|
57
125
|
|
|
58
|
-
|
|
126
|
+
#### 비디오 광고
|
|
127
|
+
```typescript
|
|
128
|
+
const videoId = AdStage.ads.video('container-id', {
|
|
129
|
+
width: 640,
|
|
130
|
+
height: 360,
|
|
131
|
+
autoplay: false, // 자동 재생
|
|
132
|
+
muted: true, // 음소거
|
|
133
|
+
onClick: (adData) => {
|
|
134
|
+
console.log('Video ad clicked:', adData);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
#### 광고 관리
|
|
140
|
+
```typescript
|
|
141
|
+
// 광고 새로고침
|
|
59
142
|
AdStage.ads.refresh('slot-id');
|
|
143
|
+
|
|
144
|
+
// 광고 제거
|
|
60
145
|
AdStage.ads.destroy('slot-id');
|
|
146
|
+
|
|
147
|
+
// 모든 광고 슬롯 조회
|
|
61
148
|
const allSlots = AdStage.ads.getAllSlots();
|
|
149
|
+
|
|
150
|
+
// 특정 슬롯 조회
|
|
151
|
+
const slot = AdStage.ads.getSlotById('slot-id');
|
|
62
152
|
```
|
|
63
153
|
|
|
64
|
-
###
|
|
154
|
+
### 설정 모듈 (AdStage.config)
|
|
65
155
|
|
|
66
156
|
```typescript
|
|
67
|
-
|
|
157
|
+
// 현재 설정 조회
|
|
158
|
+
const config = AdStage.config.getConfig();
|
|
68
159
|
|
|
69
|
-
//
|
|
70
|
-
AdStage.
|
|
71
|
-
|
|
72
|
-
|
|
160
|
+
// 디버그 모드 확인
|
|
161
|
+
const isDebug = AdStage.config.isDebugMode();
|
|
162
|
+
|
|
163
|
+
// 모듈 활성화 확인
|
|
164
|
+
const isAdsEnabled = AdStage.config.isModuleEnabled('ads');
|
|
165
|
+
|
|
166
|
+
// 런타임 설정 변경
|
|
167
|
+
AdStage.config.updateConfig({
|
|
168
|
+
debug: false,
|
|
169
|
+
timeout: 15000
|
|
73
170
|
});
|
|
74
171
|
|
|
75
|
-
//
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
172
|
+
// API 엔드포인트 확인
|
|
173
|
+
const endpoint = AdStage.config.getApiEndpoint();
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### 이벤트 모듈 (AdStage.events) - 기본 구조
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
// 커스텀 이벤트 추적
|
|
180
|
+
await AdStage.events.track('button_click', {
|
|
181
|
+
button_id: 'cta',
|
|
182
|
+
page: '/pricing'
|
|
79
183
|
});
|
|
80
184
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
185
|
+
// 페이지 뷰 추적
|
|
186
|
+
await AdStage.events.pageView({
|
|
187
|
+
page: '/products',
|
|
188
|
+
title: 'Products Page',
|
|
189
|
+
category: 'shopping'
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// 사용자 액션 추적
|
|
193
|
+
await AdStage.events.userAction('form_submit', {
|
|
194
|
+
form_id: 'contact',
|
|
195
|
+
email: 'user@example.com'
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// 배치 이벤트 처리
|
|
199
|
+
AdStage.events.batch.start();
|
|
200
|
+
AdStage.events.batch.add('event1', { data: 'value1' });
|
|
201
|
+
AdStage.events.batch.add('event2', { data: 'value2' });
|
|
202
|
+
await AdStage.events.batch.flush();
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## 🔧 고급 설정
|
|
206
|
+
|
|
207
|
+
### 모듈 선택적 로딩
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
// 광고 기능만 사용 (~15KB)
|
|
211
|
+
AdStage.init({
|
|
212
|
+
apiKey: 'your-api-key',
|
|
213
|
+
modules: ['ads']
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
// 모든 기능 사용 (~28KB)
|
|
217
|
+
AdStage.init({
|
|
218
|
+
apiKey: 'your-api-key',
|
|
219
|
+
modules: ['ads', 'events', 'config']
|
|
84
220
|
});
|
|
85
221
|
```
|
|
86
222
|
|
|
87
|
-
|
|
223
|
+
### 환경별 설정
|
|
88
224
|
|
|
89
|
-
### 1. 모듈 독립성
|
|
90
225
|
```typescript
|
|
91
|
-
//
|
|
226
|
+
// 개발 환경
|
|
92
227
|
AdStage.init({
|
|
93
|
-
|
|
228
|
+
apiKey: 'dev-api-key',
|
|
229
|
+
baseUrl: 'https://beta-api.adstage.app', // 베타 환경
|
|
230
|
+
debug: true,
|
|
231
|
+
validateOnInit: false
|
|
94
232
|
});
|
|
95
233
|
|
|
234
|
+
// 프로덕션 환경
|
|
96
235
|
AdStage.init({
|
|
97
|
-
|
|
236
|
+
apiKey: 'prod-api-key',
|
|
237
|
+
baseUrl: 'https://api.adstage.io', // 프로덕션 환경
|
|
238
|
+
debug: false,
|
|
239
|
+
productionMode: true,
|
|
240
|
+
timeout: 10000
|
|
98
241
|
});
|
|
99
242
|
```
|
|
100
243
|
|
|
101
|
-
###
|
|
244
|
+
### 오류 처리
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
AdStage.init({
|
|
248
|
+
apiKey: 'your-api-key',
|
|
249
|
+
fallbackMode: true, // 네트워크 오류 시 fallback 모드
|
|
250
|
+
offlineMode: false, // 오프라인 모드 비활성화
|
|
251
|
+
debug: true
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
try {
|
|
255
|
+
const bannerId = AdStage.ads.banner('container');
|
|
256
|
+
} catch (error) {
|
|
257
|
+
console.error('광고 로드 실패:', error);
|
|
258
|
+
// fallback 처리
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## 📱 React 통합
|
|
263
|
+
|
|
264
|
+
```tsx
|
|
265
|
+
import React, { useEffect, useRef } from 'react';
|
|
266
|
+
import { AdStage } from '@adstage/web-sdk';
|
|
267
|
+
|
|
268
|
+
// React 컴포넌트 예제
|
|
269
|
+
function AdBanner({ adType = 'banner', options = {} }) {
|
|
270
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
271
|
+
const slotIdRef = useRef<string | null>(null);
|
|
272
|
+
|
|
273
|
+
useEffect(() => {
|
|
274
|
+
if (!containerRef.current) return;
|
|
275
|
+
|
|
276
|
+
// SDK 초기화 (한 번만)
|
|
277
|
+
if (!AdStage.config.isReady()) {
|
|
278
|
+
AdStage.init({
|
|
279
|
+
apiKey: process.env.REACT_APP_ADSTAGE_API_KEY!,
|
|
280
|
+
debug: process.env.NODE_ENV === 'development'
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// 광고 생성
|
|
285
|
+
const containerId = `ad-container-${Date.now()}`;
|
|
286
|
+
containerRef.current.id = containerId;
|
|
287
|
+
|
|
288
|
+
slotIdRef.current = AdStage.ads[adType](containerId, options);
|
|
289
|
+
|
|
290
|
+
// 정리
|
|
291
|
+
return () => {
|
|
292
|
+
if (slotIdRef.current) {
|
|
293
|
+
AdStage.ads.destroy(slotIdRef.current);
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
}, [adType, options]);
|
|
297
|
+
|
|
298
|
+
return <div ref={containerRef} />;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// 사용법
|
|
302
|
+
function App() {
|
|
303
|
+
return (
|
|
304
|
+
<div>
|
|
305
|
+
<AdBanner
|
|
306
|
+
adType="banner"
|
|
307
|
+
options={{ width: '100%', height: 250 }}
|
|
308
|
+
/>
|
|
309
|
+
<AdBanner
|
|
310
|
+
adType="text"
|
|
311
|
+
options={{ maxLines: 3, style: 'card' }}
|
|
312
|
+
/>
|
|
313
|
+
</div>
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
## 🏗 아키텍처 & 특징
|
|
319
|
+
|
|
320
|
+
### 네임스페이스 아키텍처
|
|
321
|
+
모든 기능이 `AdStage` 네임스페이스 하위에 체계적으로 구성되어 다른 라이브러리와의 충돌을 방지합니다.
|
|
322
|
+
|
|
323
|
+
```typescript
|
|
324
|
+
AdStage.ads.banner() // 광고 기능
|
|
325
|
+
AdStage.config.update() // 설정 관리
|
|
326
|
+
AdStage.events.track() // 이벤트 추적
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### 모듈 시스템
|
|
330
|
+
필요한 기능만 선택적으로 로드하여 번들 크기를 최적화할 수 있습니다.
|
|
331
|
+
|
|
332
|
+
| 모듈 조합 | 크기 | 포함 기능 |
|
|
333
|
+
|-----------|------|-----------|
|
|
334
|
+
| `['ads']` | ~15KB | 광고 표시만 |
|
|
335
|
+
| `['ads', 'config']` | ~20KB | 광고 + 설정 관리 |
|
|
336
|
+
| `['ads', 'events', 'config']` | ~28KB | 모든 기능 |
|
|
337
|
+
|
|
338
|
+
### TypeScript 완전 지원
|
|
339
|
+
모든 API에 대한 완전한 타입 정의를 제공하여 개발 경험을 향상시킵니다.
|
|
340
|
+
|
|
102
341
|
```typescript
|
|
103
|
-
// TypeScript 완전 지원
|
|
104
342
|
interface AdStageConfig {
|
|
105
343
|
apiKey: string;
|
|
106
344
|
debug?: boolean;
|
|
107
345
|
modules?: ModuleName[];
|
|
346
|
+
baseUrl?: string;
|
|
347
|
+
timeout?: number;
|
|
108
348
|
}
|
|
109
349
|
|
|
110
|
-
// 자동완성
|
|
350
|
+
// 자동완성 및 타입 검사
|
|
111
351
|
AdStage.ads.banner('container', {
|
|
112
|
-
width: '100%', // ✅ string
|
|
352
|
+
width: '100%', // ✅ string | number
|
|
113
353
|
height: 250, // ✅ number
|
|
114
354
|
autoSlide: true // ✅ boolean
|
|
115
355
|
});
|
|
116
356
|
```
|
|
117
357
|
|
|
118
|
-
###
|
|
358
|
+
### 동기 초기화
|
|
359
|
+
`await` 없이 즉시 사용 가능한 동기 API로 설계되어 개발이 간편합니다.
|
|
360
|
+
|
|
119
361
|
```typescript
|
|
120
|
-
//
|
|
121
|
-
AdStage.
|
|
122
|
-
AdStage.
|
|
123
|
-
|
|
362
|
+
// ✅ 동기 - 즉시 사용 가능
|
|
363
|
+
AdStage.init({ apiKey: 'key' });
|
|
364
|
+
const id = AdStage.ads.banner('container');
|
|
365
|
+
|
|
366
|
+
// ❌ 비동기 - 복잡한 처리 필요
|
|
367
|
+
await AdStage.init({ apiKey: 'key' });
|
|
368
|
+
const id = await AdStage.ads.banner('container');
|
|
124
369
|
```
|
|
125
370
|
|
|
126
|
-
## 📊 번들 크기
|
|
371
|
+
## 📊 번들 크기 & 성능
|
|
127
372
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
373
|
+
### 최적화된 번들 크기
|
|
374
|
+
```
|
|
375
|
+
dist/
|
|
376
|
+
├── index.esm.js # ES 모듈 (28KB gzipped)
|
|
377
|
+
├── index.cjs.js # CommonJS (30KB gzipped)
|
|
378
|
+
├── index.umd.js # UMD 브라우저 (32KB gzipped)
|
|
379
|
+
└── index.d.ts # TypeScript 타입 정의
|
|
380
|
+
```
|
|
133
381
|
|
|
134
|
-
|
|
382
|
+
### Tree Shaking 지원
|
|
383
|
+
ES 모듈 형태로 제공되어 번들러의 tree shaking으로 사용하지 않는 코드 제거가 가능합니다.
|
|
135
384
|
|
|
136
|
-
### Q1 2025: 이벤트 시스템
|
|
137
385
|
```typescript
|
|
138
|
-
//
|
|
139
|
-
|
|
140
|
-
AdStage.events.userAction('button_click', { button_id: 'cta' });
|
|
386
|
+
// 필요한 모듈만 임포트
|
|
387
|
+
import { AdStage } from '@adstage/web-sdk';
|
|
141
388
|
|
|
142
|
-
//
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
389
|
+
// 특정 타입만 임포트
|
|
390
|
+
import type { AdStageConfig, AdOptions } from '@adstage/web-sdk';
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
### Lazy 로딩 시스템
|
|
394
|
+
광고 콘텐츠는 백그라운드에서 로드되어 사용자 경험을 향상시킵니다.
|
|
395
|
+
|
|
396
|
+
```typescript
|
|
397
|
+
// 1. 즉시 placeholder 표시
|
|
398
|
+
const id = AdStage.ads.banner('container');
|
|
399
|
+
|
|
400
|
+
// 2. 백그라운드에서 광고 로드
|
|
401
|
+
// 3. 로드 완료 시 실제 광고로 교체
|
|
146
402
|
```
|
|
147
403
|
|
|
148
|
-
##
|
|
404
|
+
## 🔌 브라우저 지원
|
|
405
|
+
|
|
406
|
+
- **모던 브라우저**: Chrome 80+, Firefox 80+, Safari 14+, Edge 80+
|
|
407
|
+
- **ES 모듈**: ES2018+ 지원 브라우저
|
|
408
|
+
- **폴리필**: 필요시 별도 제공
|
|
409
|
+
- **SSR 안전**: Next.js, Nuxt.js 등 SSR 프레임워크 지원
|
|
149
410
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
- [x] **Lazy 로딩 시스템** (즉시 placeholder, 백그라운드 광고 로드)
|
|
157
|
-
- [x] TypeScript 타입 정의
|
|
158
|
-
- [x] 예제 및 문서
|
|
411
|
+
```typescript
|
|
412
|
+
// SSR 환경에서 안전하게 사용
|
|
413
|
+
if (typeof window !== 'undefined') {
|
|
414
|
+
AdStage.init({ apiKey: 'your-key' });
|
|
415
|
+
}
|
|
416
|
+
```
|
|
159
417
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
418
|
+
## 🚧 개발 상태
|
|
419
|
+
|
|
420
|
+
### ✅ 완료된 기능
|
|
421
|
+
- [x] **네임스페이스 아키텍처** - 충돌 방지 및 체계적 구조
|
|
422
|
+
- [x] **동기 초기화 시스템** - `await` 없는 즉시 사용 가능
|
|
423
|
+
- [x] **광고 모듈 (AdsModule)** - 5가지 광고 타입 완전 구현
|
|
424
|
+
- [x] 배너, 텍스트, 비디오, 네이티브, 전면 광고
|
|
425
|
+
- [x] 자동 슬라이더 및 페이드 효과
|
|
426
|
+
- [x] Lazy 로딩 시스템
|
|
427
|
+
- [x] 이벤트 추적 및 중복 방지
|
|
428
|
+
- [x] **설정 모듈 (ConfigModule)** - 동기 설정 관리
|
|
429
|
+
- [x] 환경 자동 감지
|
|
430
|
+
- [x] 런타임 설정 변경
|
|
431
|
+
- [x] 모듈 선택적 로딩
|
|
432
|
+
- [x] **TypeScript 타입 정의** - 완전한 타입 안전성
|
|
433
|
+
- [x] **다중 빌드 타겟** - ESM/CJS/UMD 지원
|
|
434
|
+
- [x] **SSR 지원** - Next.js, Nuxt.js 등 호환
|
|
435
|
+
|
|
436
|
+
### 🚧 기본 구조 완성 (향후 구현)
|
|
437
|
+
- [ ] **이벤트 모듈 (EventsModule)** - Q1 2025 구현 예정
|
|
438
|
+
- [x] 기본 인터페이스 및 메소드 구조
|
|
439
|
+
- [ ] 실제 서버 통신 로직
|
|
440
|
+
- [ ] 배치 처리 시스템
|
|
441
|
+
- [ ] 오프라인 지원
|
|
163
442
|
|
|
164
443
|
### 📋 다음 단계
|
|
165
444
|
1. **Q1 2025**: EventsModule 완전 구현
|
|
445
|
+
2. **Q2 2025**: 성능 최적화 및 고급 타겟팅
|
|
446
|
+
3. **Q3 2025**: A/B 테스트 및 개인화 기능
|
|
166
447
|
|
|
167
448
|
## 🛠 개발 가이드
|
|
168
449
|
|
|
@@ -170,36 +451,117 @@ AdStage.events.batch.flush(); // 백그라운드 전송
|
|
|
170
451
|
```
|
|
171
452
|
src/
|
|
172
453
|
├── core/
|
|
173
|
-
│ └── AdStage.ts
|
|
454
|
+
│ └── AdStage.ts # 메인 네임스페이스 클래스
|
|
174
455
|
├── modules/
|
|
175
|
-
│ ├── ads/
|
|
176
|
-
│
|
|
177
|
-
│
|
|
178
|
-
|
|
179
|
-
│
|
|
180
|
-
│
|
|
456
|
+
│ ├── ads/ # ✅ 광고 모듈 (완전 구현)
|
|
457
|
+
│ │ └── AdsModule.ts
|
|
458
|
+
│ ├── config/ # ✅ 설정 모듈 (완전 구현)
|
|
459
|
+
│ │ └── ConfigModule.ts
|
|
460
|
+
│ └── events/ # 🚧 이벤트 모듈 (기본 구조)
|
|
461
|
+
│ └── EventsModule.ts
|
|
462
|
+
├── managers/ # 기능별 관리 클래스
|
|
463
|
+
│ ├── event-tracker.ts # 이벤트 추적
|
|
464
|
+
│ ├── viewable-tracker.ts # 중복 노출 방지
|
|
465
|
+
│ ├── carousel-slider-manager.ts # 슬라이더 관리
|
|
466
|
+
│ └── text-transition-manager.ts # 텍스트 전환 효과
|
|
467
|
+
├── types/ # TypeScript 타입 정의
|
|
468
|
+
│ ├── config.ts # SDK 설정 타입
|
|
469
|
+
│ ├── advertisement.ts # 광고 관련 타입
|
|
470
|
+
│ ├── events.ts # 이벤트 관련 타입
|
|
471
|
+
│ └── api.ts # API 응답 타입
|
|
472
|
+
├── utils/ # 유틸리티 함수
|
|
473
|
+
│ ├── sdk-utils.ts # SDK 공통 유틸
|
|
474
|
+
│ ├── dom-utils.ts # DOM 조작 유틸
|
|
475
|
+
│ └── api-headers.ts # API 헤더 생성
|
|
181
476
|
├── constants/
|
|
182
|
-
│ └── endpoints.ts
|
|
183
|
-
└── index.ts
|
|
477
|
+
│ └── endpoints.ts # API 엔드포인트 관리
|
|
478
|
+
└── index.ts # 메인 익스포트
|
|
184
479
|
```
|
|
185
480
|
|
|
186
|
-
###
|
|
187
|
-
- **클래스/네임스페이스**: `AdStage` (대문자)
|
|
188
|
-
- **타입**: `AdStageConfig` (대문자)
|
|
189
|
-
- **함수/변수**: `adstageInit`, `adstageConfig` (camelCase)
|
|
481
|
+
### 로컬 개발
|
|
190
482
|
|
|
191
|
-
|
|
483
|
+
```bash
|
|
484
|
+
# 의존성 설치
|
|
485
|
+
pnpm install
|
|
486
|
+
|
|
487
|
+
# 개발 모드 (watch)
|
|
488
|
+
pnpm run dev
|
|
192
489
|
|
|
193
|
-
|
|
490
|
+
# 타입 체크
|
|
491
|
+
pnpm run lint
|
|
492
|
+
|
|
493
|
+
# 빌드
|
|
494
|
+
pnpm run build
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
### 네이밍 규칙
|
|
498
|
+
- **클래스/네임스페이스**: PascalCase (`AdStage`, `AdsModule`)
|
|
499
|
+
- **인터페이스/타입**: PascalCase (`AdStageConfig`, `Advertisement`)
|
|
500
|
+
- **함수/변수**: camelCase (`init`, `isReady`)
|
|
501
|
+
- **상수**: UPPER_SNAKE_CASE (`API_ENDPOINTS`, `DEFAULT_CONFIG`)
|
|
502
|
+
|
|
503
|
+
### 코딩 스타일
|
|
504
|
+
- **TypeScript strict 모드** 활성화
|
|
505
|
+
- **ESLint + Prettier** 자동 포맷팅
|
|
506
|
+
- **JSDoc 주석** 모든 public API에 필수
|
|
507
|
+
- **에러 처리** 모든 async 함수에 try-catch
|
|
194
508
|
|
|
195
509
|
## 🤝 기여하기
|
|
196
510
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
511
|
+
### 버그 리포트
|
|
512
|
+
이슈를 발견하셨다면 다음 정보와 함께 GitHub Issues에 신고해 주세요:
|
|
513
|
+
|
|
514
|
+
- SDK 버전
|
|
515
|
+
- 브라우저 및 버전
|
|
516
|
+
- 재현 단계
|
|
517
|
+
- 예상 동작 vs 실제 동작
|
|
518
|
+
- 최소 재현 코드
|
|
519
|
+
|
|
520
|
+
### 기능 요청
|
|
521
|
+
새로운 기능이나 개선사항이 있다면 제안해 주세요:
|
|
522
|
+
|
|
523
|
+
1. GitHub Issues에서 기능 요청 템플릿 사용
|
|
524
|
+
2. 사용 사례 및 동기 설명
|
|
525
|
+
3. 예상 API 디자인 제안
|
|
526
|
+
|
|
527
|
+
### 개발 기여
|
|
528
|
+
|
|
529
|
+
```bash
|
|
530
|
+
# 1. 포크 및 클론
|
|
531
|
+
git clone https://github.com/your-username/adstage.git
|
|
532
|
+
cd adstage/sdk
|
|
533
|
+
|
|
534
|
+
# 2. 의존성 설치
|
|
535
|
+
pnpm install
|
|
536
|
+
|
|
537
|
+
# 3. 기능 브랜치 생성
|
|
538
|
+
git checkout -b feature/amazing-feature
|
|
539
|
+
|
|
540
|
+
# 4. 개발 및 테스트
|
|
541
|
+
pnpm run dev
|
|
542
|
+
pnpm run build
|
|
543
|
+
pnpm run lint
|
|
544
|
+
|
|
545
|
+
# 5. 커밋 및 푸시
|
|
546
|
+
git commit -m '✨ Add amazing feature'
|
|
547
|
+
git push origin feature/amazing-feature
|
|
548
|
+
|
|
549
|
+
# 6. Pull Request 생성
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
## 📄 라이선스
|
|
553
|
+
|
|
554
|
+
MIT License © 2024 AdStage
|
|
555
|
+
|
|
556
|
+
자세한 내용은 [LICENSE](./LICENSE) 파일을 참조하세요.
|
|
557
|
+
|
|
558
|
+
## 🔗 링크
|
|
559
|
+
|
|
560
|
+
- [📖 공식 문서](https://docs.adstage.io)
|
|
561
|
+
- [🐛 이슈 신고](https://github.com/nbase-io/adstage/issues)
|
|
562
|
+
- [💬 디스커션](https://github.com/nbase-io/adstage/discussions)
|
|
563
|
+
- [📦 NPM 패키지](https://www.npmjs.com/package/@adstage/web-sdk)
|
|
202
564
|
|
|
203
565
|
---
|
|
204
566
|
|
|
205
|
-
**AdStage Web SDK** -
|
|
567
|
+
**AdStage Web SDK** - 프로덕션 환경에서 검증된 마케팅 플랫폼 통합 솔루션
|