@adstage/web-sdk 1.3.4 → 1.4.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.
Files changed (61) hide show
  1. package/README.md +178 -35
  2. package/dist/index.cjs.js +753 -509
  3. package/dist/index.d.ts +286 -97
  4. package/dist/index.esm.js +737 -485
  5. package/dist/index.standalone.js +737 -485
  6. package/package.json +1 -1
  7. package/src/constants/endpoints.ts +93 -0
  8. package/src/core/AdStage.ts +128 -0
  9. package/src/index.ts +14 -432
  10. package/src/managers/{slider-manager.ts → carousel-slider-manager.ts} +9 -8
  11. package/src/managers/event-tracker.ts +2 -4
  12. package/src/managers/{fade-slider-manager.ts → text-transition-manager.ts} +7 -7
  13. package/src/modules/ads/AdsModule.ts +525 -0
  14. package/src/modules/config/ConfigModule.ts +124 -0
  15. package/src/modules/deeplinks/DeeplinksModule.ts +0 -0
  16. package/src/modules/events/EventsModule.ts +106 -0
  17. package/src/types/config.ts +74 -3
  18. package/src/types/index.ts +2 -1
  19. package/src/utils/api-headers.ts +52 -0
  20. package/src/utils/dom-utils.ts +1 -1
  21. package/examples/README.md +0 -33
  22. package/examples/banner-ads.html +0 -512
  23. package/examples/index.html +0 -338
  24. package/examples/native-ads.html +0 -634
  25. package/examples/react-app/README.md +0 -70
  26. package/examples/react-app/index.html +0 -13
  27. package/examples/react-app/package-lock.json +0 -3042
  28. package/examples/react-app/package.json +0 -26
  29. package/examples/react-app/pnpm-lock.yaml +0 -1857
  30. package/examples/react-app/public/index.standalone.js +0 -2331
  31. package/examples/react-app/src/App.tsx +0 -226
  32. package/examples/react-app/src/index.css +0 -37
  33. package/examples/react-app/src/main.tsx +0 -10
  34. package/examples/react-app/tsconfig.json +0 -25
  35. package/examples/react-app/tsconfig.node.json +0 -10
  36. package/examples/react-app/vite.config.ts +0 -15
  37. package/examples/react-nextjs/app/globals.css +0 -200
  38. package/examples/react-nextjs/app/layout.tsx +0 -27
  39. package/examples/react-nextjs/app/page.tsx +0 -258
  40. package/examples/react-nextjs/next.config.js +0 -9
  41. package/examples/react-nextjs/package.json +0 -22
  42. package/examples/react-nextjs/pnpm-lock.yaml +0 -343
  43. package/examples/react-nextjs/tsconfig.json +0 -34
  44. package/examples/text-ads.html +0 -597
  45. package/examples/video-ads.html +0 -739
  46. package/src/react/components/AdErrorBoundary.tsx +0 -75
  47. package/src/react/components/AdSlot.tsx +0 -144
  48. package/src/react/components/BannerAd.tsx +0 -24
  49. package/src/react/components/InterstitialAd.tsx +0 -24
  50. package/src/react/components/NativeAd.tsx +0 -24
  51. package/src/react/components/TextAd.tsx +0 -24
  52. package/src/react/components/VideoAd.tsx +0 -24
  53. package/src/react/components/index.ts +0 -8
  54. package/src/react/hooks/index.ts +0 -4
  55. package/src/react/hooks/useAdSlot.ts +0 -83
  56. package/src/react/hooks/useAdStage.ts +0 -14
  57. package/src/react/hooks/useAdTracking.ts +0 -61
  58. package/src/react/index.ts +0 -4
  59. package/src/react/providers/AdStageProvider.tsx +0 -86
  60. package/src/react/providers/index.ts +0 -2
  61. package/src/utils/sdk-standalone.ts +0 -155
@@ -1,512 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="ko">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>배너 광고 예제 - AdStage SDK</title>
7
- <style>
8
- * {
9
- box-sizing: border-box;
10
- margin: 0;
11
- padding: 0;
12
- }
13
-
14
- body {
15
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
16
- line-height: 1.6;
17
- color: #333;
18
- background: #f8f9fa;
19
- padding: 20px;
20
- }
21
-
22
- .container {
23
- max-width: 1200px;
24
- margin: 0 auto;
25
- background: white;
26
- border-radius: 12px;
27
- box-shadow: 0 4px 12px rgba(0,0,0,0.1);
28
- overflow: hidden;
29
- }
30
-
31
- .header {
32
- background: linear-gradient(135deg, #667eea, #764ba2);
33
- color: white;
34
- padding: 30px;
35
- text-align: center;
36
- }
37
-
38
- .header h1 {
39
- font-size: 2rem;
40
- margin-bottom: 10px;
41
- }
42
-
43
- .header p {
44
- opacity: 0.9;
45
- }
46
-
47
- .nav {
48
- background: #f8f9fa;
49
- padding: 15px 30px;
50
- border-bottom: 1px solid #dee2e6;
51
- }
52
-
53
- .back-link {
54
- color: #667eea;
55
- text-decoration: none;
56
- font-weight: 500;
57
- }
58
-
59
- .back-link:hover {
60
- text-decoration: underline;
61
- }
62
-
63
- .content {
64
- padding: 30px;
65
- }
66
-
67
- .section {
68
- margin-bottom: 40px;
69
- }
70
-
71
- .section h2 {
72
- color: #495057;
73
- margin-bottom: 20px;
74
- padding-bottom: 10px;
75
- border-bottom: 2px solid #667eea;
76
- }
77
-
78
- .ad-grid {
79
- display: grid;
80
- grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
81
- gap: 30px;
82
- margin-bottom: 30px;
83
- }
84
-
85
- .ad-container {
86
- border: 2px solid #e9ecef;
87
- border-radius: 12px;
88
- padding: 20px;
89
- background: #f8f9fa;
90
- transition: all 0.3s ease;
91
- }
92
-
93
- .ad-container:hover {
94
- border-color: #667eea;
95
- box-shadow: 0 4px 12px rgba(102, 126, 234, 0.15);
96
- }
97
-
98
- .ad-container h3 {
99
- margin-bottom: 15px;
100
- color: #667eea;
101
- font-size: 1.1rem;
102
- }
103
-
104
- .ad-slot {
105
- background: white;
106
- border: 2px dashed #dee2e6;
107
- border-radius: 8px;
108
- padding: 20px;
109
- text-align: center;
110
- min-height: 120px;
111
- display: flex;
112
- align-items: center;
113
- justify-content: center;
114
- position: relative;
115
- transition: all 0.3s ease;
116
- }
117
-
118
- .ad-slot:hover {
119
- border-color: #667eea;
120
- background: #f8f9ff;
121
- }
122
-
123
- .ad-slot.loading::before {
124
- content: "📡 광고 로딩 중...";
125
- color: #6c757d;
126
- font-size: 0.9rem;
127
- }
128
-
129
- .ad-slot.loaded::before {
130
- content: "✅ 광고 로딩 완료";
131
- color: #28a745;
132
- font-size: 0.9rem;
133
- }
134
-
135
- .ad-slot.error::before {
136
- content: "❌ 광고 로딩 실패";
137
- color: #dc3545;
138
- font-size: 0.9rem;
139
- }
140
-
141
- .ad-info {
142
- margin-top: 15px;
143
- padding: 10px;
144
- background: #e9ecef;
145
- border-radius: 6px;
146
- font-size: 0.9rem;
147
- color: #6c757d;
148
- }
149
-
150
- .controls {
151
- display: flex;
152
- gap: 10px;
153
- margin-top: 15px;
154
- flex-wrap: wrap;
155
- }
156
-
157
- .btn {
158
- padding: 8px 16px;
159
- border: none;
160
- border-radius: 6px;
161
- background: #667eea;
162
- color: white;
163
- cursor: pointer;
164
- font-size: 0.9rem;
165
- transition: background 0.3s ease;
166
- }
167
-
168
- .btn:hover {
169
- background: #5a67d8;
170
- }
171
-
172
- .btn.secondary {
173
- background: #6c757d;
174
- }
175
-
176
- .btn.secondary:hover {
177
- background: #5a6268;
178
- }
179
-
180
- .status {
181
- margin-top: 30px;
182
- padding: 20px;
183
- background: #e7f3ff;
184
- border-left: 4px solid #0066cc;
185
- border-radius: 4px;
186
- }
187
-
188
- .code-example {
189
- background: #2d3748;
190
- color: #e2e8f0;
191
- padding: 20px;
192
- border-radius: 8px;
193
- font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
194
- font-size: 0.9rem;
195
- overflow-x: auto;
196
- margin: 15px 0;
197
- }
198
-
199
- .large-banner {
200
- min-height: 250px;
201
- }
202
-
203
- .medium-banner {
204
- min-height: 200px;
205
- }
206
-
207
- .small-banner {
208
- min-height: 120px;
209
- }
210
-
211
- .log {
212
- background: #f8f9fa;
213
- border: 1px solid #dee2e6;
214
- border-radius: 6px;
215
- padding: 15px;
216
- max-height: 200px;
217
- overflow-y: auto;
218
- font-family: monospace;
219
- font-size: 0.8rem;
220
- margin-top: 15px;
221
- }
222
-
223
- .log-entry {
224
- margin-bottom: 5px;
225
- padding: 2px 5px;
226
- border-radius: 3px;
227
- }
228
-
229
- .log-entry.info {
230
- background: #d4edda;
231
- color: #155724;
232
- }
233
-
234
- .log-entry.warn {
235
- background: #fff3cd;
236
- color: #856404;
237
- }
238
-
239
- .log-entry.error {
240
- background: #f8d7da;
241
- color: #721c24;
242
- }
243
- </style>
244
- </head>
245
- <body>
246
- <div class="container">
247
- <div class="header">
248
- <h1>🖼️ 배너 광고 예제</h1>
249
- <p>다양한 크기와 형태의 배너 광고 표시</p>
250
- </div>
251
-
252
- <div class="nav">
253
- <a href="index.html" class="back-link">← 메인 페이지로 돌아가기</a>
254
- </div>
255
-
256
- <div class="content">
257
- <div class="section">
258
- <h2>🎯 라이브 배너 광고</h2>
259
-
260
- <div class="ad-grid">
261
- <div class="ad-container">
262
- <h3>대형 배너 (728x90)</h3>
263
- <div class="ad-slot large-banner loading"
264
- id="large-banner"
265
- adstage="large-banner"
266
- ad-type="BANNER"
267
- data-size="728x90">
268
- </div>
269
- <div class="ad-info">
270
- 슬롯 ID: large-banner<br>
271
- 크기: 728x90 (Leaderboard)<br>
272
- 위치: 페이지 상단
273
- </div>
274
- <div class="controls">
275
- <button class="btn" onclick="refreshAd('large-banner')">🔄 새로고침</button>
276
- <button class="btn secondary" onclick="hideAd('large-banner')">👁️ 숨기기</button>
277
- </div>
278
- </div>
279
-
280
- <div class="ad-container">
281
- <h3>중형 배너 (320x100)</h3>
282
- <div class="ad-slot medium-banner loading"
283
- id="medium-banner"
284
- adstage="medium-banner"
285
- ad-type="BANNER"
286
- data-size="320x100">
287
- </div>
288
- <div class="ad-info">
289
- 슬롯 ID: medium-banner<br>
290
- 크기: 320x100 (Mobile Banner)<br>
291
- 위치: 콘텐츠 중간
292
- </div>
293
- <div class="controls">
294
- <button class="btn" onclick="refreshAd('medium-banner')">🔄 새로고침</button>
295
- <button class="btn secondary" onclick="hideAd('medium-banner')">👁️ 숨기기</button>
296
- </div>
297
- </div>
298
-
299
- <div class="ad-container">
300
- <h3>소형 배너 (300x50)</h3>
301
- <div class="ad-slot small-banner loading"
302
- id="small-banner"
303
- adstage="small-banner"
304
- ad-type="BANNER"
305
- data-size="300x50">
306
- </div>
307
- <div class="ad-info">
308
- 슬롯 ID: small-banner<br>
309
- 크기: 300x50 (Mobile Banner)<br>
310
- 위치: 페이지 하단
311
- </div>
312
- <div class="controls">
313
- <button class="btn" onclick="refreshAd('small-banner')">🔄 새로고침</button>
314
- <button class="btn secondary" onclick="hideAd('small-banner')">👁️ 숨기기</button>
315
- </div>
316
- </div>
317
-
318
- <div class="ad-container">
319
- <h3>동적 배너 (유동 크기)</h3>
320
- <div class="ad-slot medium-banner loading"
321
- id="dynamic-banner"
322
- adstage="dynamic-banner"
323
- ad-type="BANNER"
324
- data-size="responsive">
325
- </div>
326
- <div class="ad-info">
327
- 슬롯 ID: dynamic-banner<br>
328
- 크기: 반응형 (Responsive)<br>
329
- 위치: 동적 콘텐츠 영역
330
- </div>
331
- <div class="controls">
332
- <button class="btn" onclick="refreshAd('dynamic-banner')">🔄 새로고침</button>
333
- <button class="btn secondary" onclick="hideAd('dynamic-banner')">👁️ 숨기기</button>
334
- </div>
335
- </div>
336
- </div>
337
- </div>
338
-
339
- <div class="section">
340
- <h2>⚡ 전체 제어</h2>
341
- <div class="controls">
342
- <button class="btn" onclick="refreshAllAds()">🔄 모든 광고 새로고침</button>
343
- <button class="btn secondary" onclick="hideAllAds()">👁️ 모든 광고 숨기기</button>
344
- <button class="btn" onclick="showAllAds()">👀 모든 광고 보이기</button>
345
- <button class="btn secondary" onclick="clearLog()">🧹 로그 지우기</button>
346
- </div>
347
- </div>
348
-
349
- <div class="section">
350
- <h2>📝 구현 코드</h2>
351
- <div class="code-example">
352
- &lt;!-- HTML: 배너 광고 슬롯 --&gt;
353
- &lt;div adstage="large-banner" ad-type="BANNER" data-size="728x90"&gt;&lt;/div&gt;
354
-
355
- &lt;script type="module"&gt;
356
- import AdStageSDK, { AdType } from '../dist/index.standalone.js';
357
-
358
- // SDK 초기화
359
- const sdk = AdStageSDK.init({
360
- apiKey: 'YOUR_API_KEY',
361
- debug: true
362
- });
363
-
364
- // 수동 광고 로드 (선택사항)
365
- sdk.loadAd('large-banner', AdType.BANNER);
366
- &lt;/script&gt;
367
- </div>
368
- </div>
369
-
370
- <div class="status" id="status">
371
- SDK 초기화 중...
372
- </div>
373
-
374
- <div class="log" id="log">
375
- <div class="log-entry info">페이지 로드 시작...</div>
376
- </div>
377
- </div>
378
- </div>
379
-
380
- <script type="module">
381
- import AdStageSDK, { AdType } from './dist/index.standalone.js';
382
-
383
- const statusEl = document.getElementById('status');
384
- const logEl = document.getElementById('log');
385
-
386
- function addLog(message, type = 'info') {
387
- const timestamp = new Date().toLocaleTimeString();
388
- const logEntry = document.createElement('div');
389
- logEntry.className = `log-entry ${type}`;
390
- logEntry.textContent = `[${timestamp}] ${message}`;
391
- logEl.appendChild(logEntry);
392
- logEl.scrollTop = logEl.scrollHeight;
393
- }
394
-
395
- function updateAdSlotStatus(slotId, status) {
396
- const slot = document.getElementById(slotId);
397
- if (slot) {
398
- slot.className = slot.className.replace(/\b(loading|loaded|error)\b/g, '');
399
- slot.classList.add(status);
400
- }
401
- }
402
-
403
- // 전역 함수들
404
- window.refreshAd = function(slotId) {
405
- addLog(`광고 새로고침 요청: ${slotId}`, 'info');
406
- updateAdSlotStatus(slotId, 'loading');
407
-
408
- try {
409
- window.adstageSDK.refreshSlot(slotId);
410
- addLog(`광고 새로고침 성공: ${slotId}`, 'info');
411
- setTimeout(() => updateAdSlotStatus(slotId, 'loaded'), 1000);
412
- } catch (error) {
413
- addLog(`광고 새로고침 실패: ${slotId} - ${error.message}`, 'error');
414
- updateAdSlotStatus(slotId, 'error');
415
- }
416
- };
417
-
418
- window.hideAd = function(slotId) {
419
- const slot = document.getElementById(slotId);
420
- if (slot) {
421
- slot.style.display = 'none';
422
- addLog(`광고 숨김: ${slotId}`, 'info');
423
- }
424
- };
425
-
426
- window.showAd = function(slotId) {
427
- const slot = document.getElementById(slotId);
428
- if (slot) {
429
- slot.style.display = 'flex';
430
- addLog(`광고 표시: ${slotId}`, 'info');
431
- }
432
- };
433
-
434
- window.refreshAllAds = function() {
435
- const slots = ['large-banner', 'medium-banner', 'small-banner', 'dynamic-banner'];
436
- slots.forEach(slotId => {
437
- setTimeout(() => refreshAd(slotId), Math.random() * 2000);
438
- });
439
- };
440
-
441
- window.hideAllAds = function() {
442
- const slots = ['large-banner', 'medium-banner', 'small-banner', 'dynamic-banner'];
443
- slots.forEach(hideAd);
444
- };
445
-
446
- window.showAllAds = function() {
447
- const slots = ['large-banner', 'medium-banner', 'small-banner', 'dynamic-banner'];
448
- slots.forEach(showAd);
449
- };
450
-
451
- window.clearLog = function() {
452
- logEl.innerHTML = '<div class="log-entry info">로그가 지워졌습니다.</div>';
453
- };
454
-
455
- try {
456
- addLog('AdStage SDK 초기화 시작...', 'info');
457
-
458
- // SDK 초기화
459
- const sdk = AdStageSDK.init({
460
- apiKey: '7dfddcfda637fbb73225bac3731688b80b90675942fe9f2057a88e2379aba2a4',
461
- debug: true
462
- });
463
-
464
- // 전역 참조 저장
465
- window.adstageSDK = sdk;
466
-
467
- statusEl.innerHTML = '✅ SDK 초기화 완료 - 실제 배너 광고 로딩 중...';
468
- statusEl.style.background = '#d4edda';
469
- statusEl.style.borderColor = '#28a745';
470
-
471
- addLog('SDK 초기화 완료', 'info');
472
- addLog('실제 API에서 광고 로딩 시작...', 'info');
473
-
474
- // 실제 API에서 광고 자동 로드
475
- await sdk.autoLoadSlots();
476
-
477
- // 광고 슬롯들에 클릭 이벤트 추가
478
- document.querySelectorAll('.ad-slot').forEach(slot => {
479
- const slotId = slot.getAttribute('adstage');
480
- const adSize = slot.getAttribute('data-size');
481
-
482
- // 클릭 이벤트
483
- slot.addEventListener('click', function() {
484
- addLog(`배너 광고 클릭: ${slotId} (${adSize})`, 'info');
485
-
486
- // 시각적 피드백
487
- this.style.background = '#e3f2fd';
488
- setTimeout(() => {
489
- this.style.background = 'white';
490
- }, 300);
491
- });
492
-
493
- // 로딩 완료 상태로 업데이트
494
- setTimeout(() => {
495
- updateAdSlotStatus(slotId, 'loaded');
496
- addLog(`실제 배너 광고 로드 완료: ${slotId}`, 'info');
497
- }, Math.random() * 3000 + 1000);
498
- });
499
-
500
- addLog('🎯 실제 API 광고 로딩 완료 - beta-api.adstage.app', 'info');
501
- console.log('배너 광고 예제 페이지 로드 완료');
502
-
503
- } catch (error) {
504
- console.error('SDK 초기화 오류:', error);
505
- addLog(`SDK 초기화 실패: ${error.message}`, 'error');
506
- statusEl.innerHTML = '❌ SDK 초기화 실패: ' + error.message;
507
- statusEl.style.background = '#f8d7da';
508
- statusEl.style.borderColor = '#dc3545';
509
- }
510
- </script>
511
- </body>
512
- </html>