@adstage/web-sdk 2.3.7 → 2.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.
- package/README.md +1 -1
- package/dist/index.cjs.js +1885 -2001
- package/dist/index.d.ts +12 -71
- package/dist/index.esm.js +1886 -1999
- package/dist/index.standalone.js +2212 -2397
- package/package.json +1 -1
- package/src/core/AdStage.ts +0 -9
- package/src/index.ts +0 -3
- package/src/managers/ads/advertisement-event-tracker.ts +8 -15
- package/src/managers/ads/carousel-slider-manager.ts +4 -35
- package/src/managers/ads/text-transition-manager.ts +1 -2
- package/src/managers/ads/viewable-event-tracker.ts +1 -5
- package/src/modules/ads/AdRenderer.ts +730 -0
- package/src/modules/ads/AdsModule.ts +27 -737
- package/src/react/AdStageProvider.tsx +0 -117
- package/src/react/index.ts +0 -11
- package/src/renderers/base-renderer.ts +5 -11
- package/src/types/advertisement.ts +17 -4
- package/src/types/api.ts +5 -1
package/package.json
CHANGED
package/src/core/AdStage.ts
CHANGED
|
@@ -7,7 +7,6 @@ import { AdStageConfig, ModuleName } from '../types/config';
|
|
|
7
7
|
import { AdsModule } from '../modules/ads/AdsModule';
|
|
8
8
|
import { ConfigModule } from '../modules/config/ConfigModule';
|
|
9
9
|
import { EventsModule } from '../modules/events/EventsModule';
|
|
10
|
-
import { endpoints } from '../constants/endpoints';
|
|
11
10
|
|
|
12
11
|
export class AdStage {
|
|
13
12
|
private static instance: AdStage;
|
|
@@ -53,14 +52,6 @@ export class AdStage {
|
|
|
53
52
|
...config
|
|
54
53
|
};
|
|
55
54
|
|
|
56
|
-
// baseUrl이 설정되었으면 endpoints에 적용
|
|
57
|
-
if (config.baseUrl) {
|
|
58
|
-
endpoints.setBaseUrl(config.baseUrl);
|
|
59
|
-
if (config.debug) {
|
|
60
|
-
console.log('🔄 API base URL set to:', config.baseUrl);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
55
|
// 모듈 동기 초기화
|
|
65
56
|
const enabledModules = instance._config.modules || ['ads', 'events', 'config'];
|
|
66
57
|
|
package/src/index.ts
CHANGED
|
@@ -6,9 +6,6 @@
|
|
|
6
6
|
// 메인 네임스페이스 클래스
|
|
7
7
|
export { default as AdStage } from './core/AdStage';
|
|
8
8
|
|
|
9
|
-
// React 통합 (선택적)
|
|
10
|
-
export { AdStageProvider, useAdStage, useAdStageSDK } from './react';
|
|
11
|
-
|
|
12
9
|
// 설정 및 타입
|
|
13
10
|
export type { AdStageConfig, ModuleName, BaseModule, ApiResponse, OrganizationInfo } from './types/config';
|
|
14
11
|
|
|
@@ -40,7 +40,12 @@ export class AdvertisementEventTracker {
|
|
|
40
40
|
}
|
|
41
41
|
): Promise<void> {
|
|
42
42
|
try {
|
|
43
|
-
//
|
|
43
|
+
// VIEWABLE 이벤트의 경우 중복 확인
|
|
44
|
+
if (eventType === AdEventType.VIEWABLE) {
|
|
45
|
+
if (ViewableEventTracker.isDuplicateViewable(adId, slotId, this.debug)) {
|
|
46
|
+
return; // 중복 viewable 이벤트이므로 추적하지 않음
|
|
47
|
+
}
|
|
48
|
+
}
|
|
44
49
|
|
|
45
50
|
// 현재 슬롯 정보 가져오기
|
|
46
51
|
const slot = this.slots.get(slotId);
|
|
@@ -60,20 +65,8 @@ export class AdvertisementEventTracker {
|
|
|
60
65
|
adType: slot?.adType || 'BANNER',
|
|
61
66
|
platform: deviceInfo.platform,
|
|
62
67
|
|
|
63
|
-
// 디바이스
|
|
64
|
-
|
|
65
|
-
osVersion: deviceInfo.osVersion,
|
|
66
|
-
deviceModel: deviceInfo.deviceModel,
|
|
67
|
-
appVersion: deviceInfo.appVersion,
|
|
68
|
-
sdkVersion: deviceInfo.sdkVersion,
|
|
69
|
-
language: deviceInfo.language,
|
|
70
|
-
country: deviceInfo.country,
|
|
71
|
-
timezone: deviceInfo.timezone,
|
|
72
|
-
viewportWidth: deviceInfo.viewportWidth,
|
|
73
|
-
viewportHeight: deviceInfo.viewportHeight,
|
|
74
|
-
screenWidth: deviceInfo.screenWidth,
|
|
75
|
-
screenHeight: deviceInfo.screenHeight,
|
|
76
|
-
connectionType: deviceInfo.connectionType,
|
|
68
|
+
// 디바이스 정보는 deviceInfo 객체로 래핑
|
|
69
|
+
deviceInfo: deviceInfo,
|
|
77
70
|
|
|
78
71
|
// 페이지 및 슬롯 정보
|
|
79
72
|
pageUrl: DOMUtils.getPageInfo().url,
|
|
@@ -39,11 +39,10 @@ export class CarouselSliderManager {
|
|
|
39
39
|
width = `${slot.width}px`;
|
|
40
40
|
}
|
|
41
41
|
containerStyles.width = width;
|
|
42
|
-
containerStyles.display = 'block'; //
|
|
42
|
+
containerStyles.display = 'inline-block'; // 지정된 크기에 맞춤 (좌측 정렬)
|
|
43
43
|
} else {
|
|
44
|
-
// 컨텐츠 크기에 맞춤
|
|
45
|
-
containerStyles.display = 'block';
|
|
46
|
-
containerStyles.width = 'fit-content'; // 컨텐츠 크기에 맞춤
|
|
44
|
+
// 컨텐츠 크기에 맞춤
|
|
45
|
+
containerStyles.display = 'inline-block';
|
|
47
46
|
}
|
|
48
47
|
|
|
49
48
|
if (slot.height && slot.height !== 0) {
|
|
@@ -184,7 +183,7 @@ export class CarouselSliderManager {
|
|
|
184
183
|
const totalSlides = advertisements.length;
|
|
185
184
|
const autoSlideInterval = (options?.autoSlideInterval || 3) * 1000; // 기본 3초
|
|
186
185
|
|
|
187
|
-
// 슬라이드 이동 함수 (무한 루프 지원
|
|
186
|
+
// 슬라이드 이동 함수 (무한 루프 지원)
|
|
188
187
|
const moveToSlide = (index: number, instant = false) => {
|
|
189
188
|
currentSlide = index;
|
|
190
189
|
|
|
@@ -198,36 +197,6 @@ export class CarouselSliderManager {
|
|
|
198
197
|
// 항상 퍼센트 기반으로 이동
|
|
199
198
|
slideContainer.style.transform = `translateX(-${(100 / extendedAds.length) * currentSlide}%)`;
|
|
200
199
|
|
|
201
|
-
// 🆕 동적 높이 조정: 현재 슬라이드의 이미지 높이에 맞춰 컨테이너 높이 조정
|
|
202
|
-
if (!instant && !slot.height && !slot.width) { // 사용자가 크기를 지정하지 않은 경우에만
|
|
203
|
-
const actualIndex = currentSlide === totalSlides ? 0 : currentSlide;
|
|
204
|
-
const currentSlideElement = slideContainer.children[currentSlide] as HTMLElement;
|
|
205
|
-
|
|
206
|
-
if (currentSlideElement) {
|
|
207
|
-
const currentAdElement = currentSlideElement.children[0] as HTMLElement;
|
|
208
|
-
if (currentAdElement) {
|
|
209
|
-
// 이미지 요소 찾기
|
|
210
|
-
const imgElement = currentAdElement.querySelector('img');
|
|
211
|
-
if (imgElement) {
|
|
212
|
-
// 이미지 로드 완료 후 높이 조정
|
|
213
|
-
const adjustHeight = () => {
|
|
214
|
-
const imgHeight = imgElement.getBoundingClientRect().height;
|
|
215
|
-
if (imgHeight > 0) {
|
|
216
|
-
sliderWrapper.style.height = `${imgHeight}px`;
|
|
217
|
-
sliderWrapper.style.transition = instant ? 'none' : 'height 0.4s ease-out';
|
|
218
|
-
}
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
if (imgElement.complete && imgElement.naturalHeight > 0) {
|
|
222
|
-
adjustHeight();
|
|
223
|
-
} else {
|
|
224
|
-
imgElement.addEventListener('load', adjustHeight, { once: true });
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
200
|
// 도트 업데이트 (무채색 스타일) - 실제 광고 인덱스 기준, 텍스트 광고가 아닐 때만
|
|
232
201
|
const actualIndex = currentSlide === totalSlides ? 0 : currentSlide;
|
|
233
202
|
if (dotContainer) {
|
|
@@ -25,8 +25,7 @@ export class TextTransitionManager {
|
|
|
25
25
|
const containerStyles: Record<string, string> = {
|
|
26
26
|
position: 'relative',
|
|
27
27
|
overflow: 'hidden',
|
|
28
|
-
display: 'block',
|
|
29
|
-
width: 'fit-content', // 컨텐츠 크기에 맞춤
|
|
28
|
+
display: 'inline-block',
|
|
30
29
|
};
|
|
31
30
|
|
|
32
31
|
// 사용자가 크기를 지정한 경우
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
export class ViewableEventTracker {
|
|
9
9
|
private static viewableTracker = new Map<string, number>();
|
|
10
|
-
private static readonly VIEWABLE_COOLDOWN =
|
|
10
|
+
private static readonly VIEWABLE_COOLDOWN = 300000; // 5분 쿨다운
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* 중복 viewable 이벤트 여부 확인
|
|
@@ -44,10 +44,6 @@ export class ViewableEventTracker {
|
|
|
44
44
|
ViewableEventTracker.viewableTracker.set(key, now);
|
|
45
45
|
sessionStorage.setItem(sessionKey, now.toString());
|
|
46
46
|
|
|
47
|
-
if (debug) {
|
|
48
|
-
console.log(`🎯 New viewable event allowed for ad ${adId} in slot ${slotId}`);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
47
|
// 오래된 세션 스토리지 데이터 정리 (선택적)
|
|
52
48
|
ViewableEventTracker.cleanupOldViewables();
|
|
53
49
|
|