@adstage/web-sdk 1.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.
Files changed (68) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +70 -0
  3. package/dist/index.cjs.js +2304 -0
  4. package/dist/index.d.ts +416 -0
  5. package/dist/index.esm.js +2288 -0
  6. package/dist/index.standalone.js +2331 -0
  7. package/examples/README.md +33 -0
  8. package/examples/banner-ads.html +512 -0
  9. package/examples/index.html +338 -0
  10. package/examples/native-ads.html +634 -0
  11. package/examples/react-app/README.md +70 -0
  12. package/examples/react-app/index.html +13 -0
  13. package/examples/react-app/package-lock.json +3042 -0
  14. package/examples/react-app/package.json +26 -0
  15. package/examples/react-app/pnpm-lock.yaml +1857 -0
  16. package/examples/react-app/public/index.standalone.js +2331 -0
  17. package/examples/react-app/src/App.tsx +226 -0
  18. package/examples/react-app/src/index.css +37 -0
  19. package/examples/react-app/src/main.tsx +10 -0
  20. package/examples/react-app/tsconfig.json +25 -0
  21. package/examples/react-app/tsconfig.node.json +10 -0
  22. package/examples/react-app/vite.config.ts +15 -0
  23. package/examples/react-nextjs/app/globals.css +200 -0
  24. package/examples/react-nextjs/app/layout.tsx +27 -0
  25. package/examples/react-nextjs/app/page.tsx +258 -0
  26. package/examples/react-nextjs/next.config.js +9 -0
  27. package/examples/react-nextjs/package.json +22 -0
  28. package/examples/react-nextjs/pnpm-lock.yaml +343 -0
  29. package/examples/react-nextjs/tsconfig.json +34 -0
  30. package/examples/text-ads.html +597 -0
  31. package/examples/video-ads.html +739 -0
  32. package/package.json +83 -0
  33. package/src/global.d.ts +20 -0
  34. package/src/index.ts +350 -0
  35. package/src/managers/device-info-collector.ts +127 -0
  36. package/src/managers/event-tracker.ts +131 -0
  37. package/src/managers/fade-slider-manager.ts +276 -0
  38. package/src/managers/impression-tracker.ts +88 -0
  39. package/src/managers/slider-manager.ts +405 -0
  40. package/src/react/components/AdErrorBoundary.tsx +75 -0
  41. package/src/react/components/AdSlot.tsx +144 -0
  42. package/src/react/components/BannerAd.tsx +24 -0
  43. package/src/react/components/InterstitialAd.tsx +24 -0
  44. package/src/react/components/NativeAd.tsx +24 -0
  45. package/src/react/components/TextAd.tsx +24 -0
  46. package/src/react/components/VideoAd.tsx +24 -0
  47. package/src/react/components/index.ts +8 -0
  48. package/src/react/hooks/index.ts +4 -0
  49. package/src/react/hooks/useAdSlot.ts +83 -0
  50. package/src/react/hooks/useAdStage.ts +14 -0
  51. package/src/react/hooks/useAdTracking.ts +61 -0
  52. package/src/react/index.ts +4 -0
  53. package/src/react/providers/AdStageProvider.tsx +86 -0
  54. package/src/react/providers/index.ts +2 -0
  55. package/src/renderers/banner-renderer.ts +35 -0
  56. package/src/renderers/base-renderer.ts +207 -0
  57. package/src/renderers/index.ts +71 -0
  58. package/src/renderers/interstitial-renderer.ts +70 -0
  59. package/src/renderers/native-renderer.ts +35 -0
  60. package/src/renderers/text-renderer.ts +94 -0
  61. package/src/renderers/video-renderer.ts +63 -0
  62. package/src/types/advertisement.ts +197 -0
  63. package/src/types/api.ts +173 -0
  64. package/src/types/config.ts +174 -0
  65. package/src/types/events.ts +60 -0
  66. package/src/types/index.ts +6 -0
  67. package/src/utils/dom-utils.ts +237 -0
  68. package/src/utils/sdk-utils.ts +134 -0
@@ -0,0 +1,416 @@
1
+ import React, { Component, ErrorInfo, ReactNode } from 'react';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+
4
+ declare enum AdType {
5
+ BANNER = "BANNER",
6
+ POPUP = "POPUP",
7
+ INTERSTITIAL = "INTERSTITIAL",
8
+ NATIVE = "NATIVE",
9
+ VIDEO = "VIDEO",
10
+ TEXT = "TEXT"
11
+ }
12
+ declare enum Platform {
13
+ WEB = "WEB",
14
+ MOBILE = "MOBILE"
15
+ }
16
+ declare enum AdEventType {
17
+ IMPRESSION = "IMPRESSION",
18
+ CLICK = "CLICK",
19
+ HOVER = "HOVER",
20
+ VIEWABLE = "VIEWABLE",
21
+ VIEWABLE_IMPRESSION = "VIEWABLE_IMPRESSION",
22
+ COMPLETED = "COMPLETED",
23
+ VIDEO_START = "VIDEO_START",
24
+ VIDEO_COMPLETE = "VIDEO_COMPLETE",
25
+ ERROR = "ERROR"
26
+ }
27
+ declare enum DeviceType {
28
+ DESKTOP = "DESKTOP",
29
+ MOBILE = "MOBILE",
30
+ TABLET = "TABLET"
31
+ }
32
+ interface Advertisement {
33
+ _id: string;
34
+ title: string;
35
+ description?: string;
36
+ adType: AdType;
37
+ orgId: string;
38
+ textContent?: string;
39
+ imageUrl?: string;
40
+ videoUrl?: string;
41
+ linkUrl: string;
42
+ startDate: Date | string;
43
+ endDate: Date | string;
44
+ status: 'ACTIVE' | 'INACTIVE' | 'PENDING';
45
+ order: number;
46
+ language: string;
47
+ countries: string[];
48
+ deviceType: DeviceType;
49
+ createdAt: Date | string;
50
+ updatedAt: Date | string;
51
+ }
52
+ interface AdSlotConfig {
53
+ type: AdType;
54
+ placement?: string;
55
+ width?: number;
56
+ height?: number;
57
+ autoRefresh?: number;
58
+ fallback?: string;
59
+ targeting?: Record<string, any>;
60
+ lazyLoad?: boolean;
61
+ responsive?: boolean;
62
+ className?: string;
63
+ style?: Partial<CSSStyleDeclaration>;
64
+ }
65
+ /**
66
+ * 가시성 메트릭스
67
+ */
68
+ interface ViewabilityMetrics {
69
+ isViewable: boolean;
70
+ visibilityRatio: number;
71
+ duration: number;
72
+ impressions: number;
73
+ attentionTime: number;
74
+ scrollDepth: number;
75
+ completionRate: number;
76
+ firstView: number;
77
+ timestamps: {
78
+ firstView: number;
79
+ lastView: number;
80
+ totalViewTime: number;
81
+ };
82
+ }
83
+ interface DeviceInfo {
84
+ deviceId: string;
85
+ platform: Platform;
86
+ osVersion?: string;
87
+ deviceModel?: string;
88
+ appVersion?: string;
89
+ sdkVersion: string;
90
+ viewport: {
91
+ width: number;
92
+ height: number;
93
+ };
94
+ screen: {
95
+ width: number;
96
+ height: number;
97
+ };
98
+ userAgent: string;
99
+ language: string;
100
+ timezone: string;
101
+ connectionType?: string;
102
+ }
103
+ interface AdEvent {
104
+ id: string;
105
+ type: AdEventType;
106
+ adId: string;
107
+ slotId: string;
108
+ timestamp: number;
109
+ deviceInfo: DeviceInfo;
110
+ contextInfo: {
111
+ pageUrl: string;
112
+ pageTitle: string;
113
+ referrer: string;
114
+ sessionId: string;
115
+ userId?: string;
116
+ };
117
+ adInfo: {
118
+ type: AdType;
119
+ placement: string;
120
+ creative: string;
121
+ campaign?: string;
122
+ targeting?: Record<string, any>;
123
+ };
124
+ viewabilityMetrics?: ViewabilityMetrics;
125
+ performanceMetrics?: {
126
+ pageLoadTime?: number;
127
+ adLoadTime?: number;
128
+ renderTime?: number;
129
+ };
130
+ abTestVariant?: string;
131
+ metadata?: Record<string, any>;
132
+ }
133
+ interface AdSlot {
134
+ id: string;
135
+ containerId: string;
136
+ adType: AdType;
137
+ width: number | string;
138
+ height: number | string;
139
+ isLoaded: boolean;
140
+ isVisible: boolean;
141
+ refreshRate: number;
142
+ lazyLoad: boolean;
143
+ targeting: Record<string, any>;
144
+ element?: HTMLElement;
145
+ config?: AdSlotConfig;
146
+ advertisement?: Advertisement;
147
+ isViewable?: boolean;
148
+ impressionSent?: boolean;
149
+ loadTime?: number;
150
+ renderTime?: number;
151
+ events?: AdEvent[];
152
+ load(): Promise<Advertisement | null>;
153
+ render(ad: Advertisement): void;
154
+ refresh(): Promise<void>;
155
+ destroy(): void;
156
+ }
157
+
158
+ interface BannerAdProps {
159
+ slotId: string;
160
+ width?: string | number;
161
+ height?: string | number;
162
+ className?: string;
163
+ style?: React.CSSProperties;
164
+ autoSlideInterval?: number;
165
+ sliderEffect?: 'slide' | 'fade';
166
+ language?: string;
167
+ deviceType?: string;
168
+ country?: string;
169
+ }
170
+ /**
171
+ * 배너 광고 전용 컴포넌트
172
+ * AdSlot의 래퍼로 adType이 BANNER로 고정됨
173
+ */
174
+ declare const BannerAd: React.FC<BannerAdProps>;
175
+
176
+ interface TextAdProps {
177
+ slotId: string;
178
+ width?: string | number;
179
+ height?: string | number;
180
+ className?: string;
181
+ style?: React.CSSProperties;
182
+ autoSlideInterval?: number;
183
+ sliderEffect?: 'slide' | 'fade';
184
+ language?: string;
185
+ deviceType?: string;
186
+ country?: string;
187
+ }
188
+ /**
189
+ * 텍스트 광고 전용 컴포넌트
190
+ * AdSlot의 래퍼로 adType이 TEXT로 고정됨
191
+ */
192
+ declare const TextAd: React.FC<TextAdProps>;
193
+
194
+ interface NativeAdProps {
195
+ slotId: string;
196
+ width?: string | number;
197
+ height?: string | number;
198
+ className?: string;
199
+ style?: React.CSSProperties;
200
+ autoSlideInterval?: number;
201
+ sliderEffect?: 'slide' | 'fade';
202
+ language?: string;
203
+ deviceType?: string;
204
+ country?: string;
205
+ }
206
+ /**
207
+ * 네이티브 광고 전용 컴포넌트
208
+ * AdSlot의 래퍼로 adType이 NATIVE로 고정됨
209
+ */
210
+ declare const NativeAd: React.FC<NativeAdProps>;
211
+
212
+ interface VideoAdProps {
213
+ slotId: string;
214
+ width?: string | number;
215
+ height?: string | number;
216
+ className?: string;
217
+ style?: React.CSSProperties;
218
+ autoSlideInterval?: number;
219
+ sliderEffect?: 'slide' | 'fade';
220
+ language?: string;
221
+ deviceType?: string;
222
+ country?: string;
223
+ }
224
+ /**
225
+ * 비디오 광고 전용 컴포넌트
226
+ * AdSlot의 래퍼로 adType이 VIDEO로 고정됨
227
+ */
228
+ declare const VideoAd: React.FC<VideoAdProps>;
229
+
230
+ interface InterstitialAdProps {
231
+ slotId: string;
232
+ width?: string | number;
233
+ height?: string | number;
234
+ className?: string;
235
+ style?: React.CSSProperties;
236
+ autoSlideInterval?: number;
237
+ sliderEffect?: 'slide' | 'fade';
238
+ language?: string;
239
+ deviceType?: string;
240
+ country?: string;
241
+ }
242
+ /**
243
+ * 인터스티셜 광고 전용 컴포넌트
244
+ * AdSlot의 래퍼로 adType이 INTERSTITIAL로 고정됨
245
+ */
246
+ declare const InterstitialAd: React.FC<InterstitialAdProps>;
247
+
248
+ interface AdErrorBoundaryProps {
249
+ children: ReactNode;
250
+ fallback?: ReactNode;
251
+ onError?: (error: Error, errorInfo: ErrorInfo) => void;
252
+ }
253
+ interface AdErrorBoundaryState {
254
+ hasError: boolean;
255
+ error: Error | null;
256
+ }
257
+ /**
258
+ * 광고 컴포넌트에서 발생하는 오류를 포착하는 Error Boundary
259
+ * 광고 로딩 실패 시 fallback UI를 표시하고 앱 전체가 크래시되는 것을 방지
260
+ */
261
+ declare class AdErrorBoundary extends Component<AdErrorBoundaryProps, AdErrorBoundaryState> {
262
+ constructor(props: AdErrorBoundaryProps);
263
+ static getDerivedStateFromError(error: Error): AdErrorBoundaryState;
264
+ componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
265
+ render(): string | number | boolean | Iterable<React.ReactNode> | react_jsx_runtime.JSX.Element | null | undefined;
266
+ }
267
+
268
+ interface AdStageSDKInstance {
269
+ createSlot: (...args: any[]) => Promise<void>;
270
+ removeSlot?: (slotId: string) => void;
271
+ }
272
+ interface AdStageContextValue {
273
+ sdk: AdStageSDKInstance | null;
274
+ isLoading: boolean;
275
+ error: string | null;
276
+ isInitialized: boolean;
277
+ }
278
+ interface AdStageProviderProps {
279
+ config: AdStageConfig;
280
+ children: ReactNode;
281
+ autoInit?: boolean;
282
+ }
283
+ declare const AdStageProvider: React.FC<AdStageProviderProps>;
284
+
285
+ /**
286
+ * AdStage SDK 인스턴스에 접근하기 위한 Hook
287
+ * AdStageProvider 내부에서만 사용 가능
288
+ */
289
+ declare const useAdStage: () => AdStageContextValue;
290
+
291
+ interface UseAdSlotOptions {
292
+ slotId: string;
293
+ containerId: string;
294
+ adType: AdType;
295
+ width?: string | number;
296
+ height?: string | number;
297
+ language?: string;
298
+ deviceType?: string;
299
+ country?: string;
300
+ autoSlideInterval?: number;
301
+ sliderEffect?: 'slide' | 'fade';
302
+ }
303
+ interface UseAdSlotReturn {
304
+ isLoading: boolean;
305
+ error: string | null;
306
+ isCreated: boolean;
307
+ createSlot: () => Promise<void>;
308
+ resetSlot: () => void;
309
+ }
310
+ /**
311
+ * 광고 슬롯 생성 및 관리를 위한 Hook
312
+ * 컴포넌트에서 직접 슬롯을 제어하고 싶을 때 사용
313
+ */
314
+ declare const useAdSlot: (options: UseAdSlotOptions) => UseAdSlotReturn;
315
+
316
+ interface UseAdTrackingReturn {
317
+ trackEvent: (adId: string, slotId: string, eventType: AdEventType) => void;
318
+ trackClick: (adId: string, slotId: string) => void;
319
+ trackImpression: (adId: string, slotId: string) => void;
320
+ trackView: (adId: string, slotId: string) => void;
321
+ trackClose: (adId: string, slotId: string) => void;
322
+ }
323
+ /**
324
+ * 광고 이벤트 추적을 위한 Hook
325
+ * 커스텀 이벤트 추적이 필요할 때 사용
326
+ */
327
+ declare const useAdTracking: () => UseAdTrackingReturn;
328
+
329
+ /**
330
+ * AdStage SDK 설정
331
+ */
332
+ interface AdStageConfig {
333
+ apiKey: string;
334
+ debug?: boolean;
335
+ }
336
+ /**
337
+ * AdStage SDK 메인 클래스
338
+ * - 간단한 API Key 기반 초기화
339
+ * - 광고 슬롯 자동 관리
340
+ * - 이벤트 자동 추적
341
+ */
342
+ declare class AdStageSDK {
343
+ private static instance;
344
+ private config;
345
+ private baseUrl;
346
+ private slots;
347
+ private initialized;
348
+ private eventTracker;
349
+ constructor(config: AdStageConfig);
350
+ /**
351
+ * SDK 초기화 및 인스턴스 반환
352
+ */
353
+ static init(config: AdStageConfig): AdStageSDK;
354
+ /**
355
+ * SDK 인스턴스 반환 (이미 초기화된 경우)
356
+ */
357
+ static getInstance(): AdStageSDK;
358
+ /**
359
+ * 광고 슬롯 생성 및 로드
360
+ */
361
+ createSlot(id: string, containerId: string, adType?: AdType, options?: {
362
+ width?: number | string;
363
+ height?: number | string;
364
+ language?: string;
365
+ deviceType?: string;
366
+ country?: string;
367
+ autoSlideInterval?: number;
368
+ sliderEffect?: 'slide' | 'fade';
369
+ }): Promise<void>;
370
+ /**
371
+ * 광고 슬롯 로드
372
+ */
373
+ private loadSlot;
374
+ /**
375
+ * 광고 슬롯 렌더링 (슬라이더 포함)
376
+ */
377
+ private renderSlotWithSlider;
378
+ /**
379
+ * 광고 슬롯 렌더링 (단일 광고용)
380
+ */
381
+ private renderSlot;
382
+ /**
383
+ * 광고 슬롯 새로고침
384
+ */
385
+ refreshSlot(slotId: string): Promise<void>;
386
+ /**
387
+ * 광고 슬롯 제거
388
+ */
389
+ destroySlot(slotId: string): void;
390
+ /**
391
+ * 자동 슬롯 검색 및 로드 (분리된 SDKUtils 사용)
392
+ */
393
+ autoLoadSlots(): Promise<void>;
394
+ /**
395
+ * SDK 정리
396
+ */
397
+ destroy(): void;
398
+ /**
399
+ * 디바이스 ID 가져오기
400
+ */
401
+ getDeviceId(): string;
402
+ /**
403
+ * 세션 ID 가져오기
404
+ */
405
+ getSessionId(): string;
406
+ /**
407
+ * 현재 로드된 슬롯 수 가져오기
408
+ */
409
+ getLoadedSlotCount(): number;
410
+ /**
411
+ * 모든 슬롯 정보 가져오기
412
+ */
413
+ getAllSlots(): Map<string, AdSlot>;
414
+ }
415
+
416
+ export { AdErrorBoundary, AdEventType, AdSlot, AdStageConfig, AdStageProvider, AdStageSDK, AdType, Advertisement, BannerAd, InterstitialAd, NativeAd, TextAd, VideoAd, AdStageSDK as default, useAdSlot, useAdStage, useAdTracking };