@adstage/web-sdk 1.1.0 → 1.3.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 +39 -47
- package/dist/index.cjs.js +124 -352
- package/dist/index.d.ts +34 -153
- package/dist/index.esm.js +117 -342
- package/dist/index.standalone.js +117 -385
- package/package.json +6 -2
- package/src/index.ts +5 -2
- package/src/utils/sdk-standalone.ts +175 -0
package/dist/index.standalone.js
CHANGED
|
@@ -1660,402 +1660,135 @@ class SDKUtils {
|
|
|
1660
1660
|
}
|
|
1661
1661
|
}
|
|
1662
1662
|
|
|
1663
|
-
var jsxRuntime = {exports: {}};
|
|
1664
|
-
|
|
1665
|
-
var reactJsxRuntime_production_min = {};
|
|
1666
|
-
|
|
1667
|
-
var react = {exports: {}};
|
|
1668
|
-
|
|
1669
|
-
var react_production_min = {};
|
|
1670
|
-
|
|
1671
1663
|
/**
|
|
1672
|
-
*
|
|
1673
|
-
*
|
|
1674
|
-
*
|
|
1675
|
-
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
1676
|
-
*
|
|
1677
|
-
* This source code is licensed under the MIT license found in the
|
|
1678
|
-
* LICENSE file in the root directory of this source tree.
|
|
1664
|
+
* AdStage SDK Standalone API
|
|
1665
|
+
* 간단하고 직관적인 사용을 위한 통합 API
|
|
1679
1666
|
*/
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
function requireReact_production_min () {
|
|
1684
|
-
if (hasRequiredReact_production_min) return react_production_min;
|
|
1685
|
-
hasRequiredReact_production_min = 1;
|
|
1686
|
-
var l=Symbol.for("react.element"),n=Symbol.for("react.portal"),p=Symbol.for("react.fragment"),q=Symbol.for("react.strict_mode"),r=Symbol.for("react.profiler"),t=Symbol.for("react.provider"),u=Symbol.for("react.context"),v=Symbol.for("react.forward_ref"),w=Symbol.for("react.suspense"),x=Symbol.for("react.memo"),y=Symbol.for("react.lazy"),z=Symbol.iterator;function A(a){if(null===a||"object"!==typeof a)return null;a=z&&a[z]||a["@@iterator"];return "function"===typeof a?a:null}
|
|
1687
|
-
var B={isMounted:function(){return !1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},C=Object.assign,D={};function E(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B;}E.prototype.isReactComponent={};
|
|
1688
|
-
E.prototype.setState=function(a,b){if("object"!==typeof a&&"function"!==typeof a&&null!=a)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,a,b,"setState");};E.prototype.forceUpdate=function(a){this.updater.enqueueForceUpdate(this,a,"forceUpdate");};function F(){}F.prototype=E.prototype;function G(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B;}var H=G.prototype=new F;
|
|
1689
|
-
H.constructor=G;C(H,E.prototype);H.isPureReactComponent=!0;var I=Array.isArray,J=Object.prototype.hasOwnProperty,K={current:null},L={key:!0,ref:!0,__self:!0,__source:!0};
|
|
1690
|
-
function M(a,b,e){var d,c={},k=null,h=null;if(null!=b)for(d in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(k=""+b.key),b)J.call(b,d)&&!L.hasOwnProperty(d)&&(c[d]=b[d]);var g=arguments.length-2;if(1===g)c.children=e;else if(1<g){for(var f=Array(g),m=0;m<g;m++)f[m]=arguments[m+2];c.children=f;}if(a&&a.defaultProps)for(d in g=a.defaultProps,g)void 0===c[d]&&(c[d]=g[d]);return {$$typeof:l,type:a,key:k,ref:h,props:c,_owner:K.current}}
|
|
1691
|
-
function N(a,b){return {$$typeof:l,type:a.type,key:b,ref:a.ref,props:a.props,_owner:a._owner}}function O(a){return "object"===typeof a&&null!==a&&a.$$typeof===l}function escape(a){var b={"=":"=0",":":"=2"};return "$"+a.replace(/[=:]/g,function(a){return b[a]})}var P=/\/+/g;function Q(a,b){return "object"===typeof a&&null!==a&&null!=a.key?escape(""+a.key):b.toString(36)}
|
|
1692
|
-
function R(a,b,e,d,c){var k=typeof a;if("undefined"===k||"boolean"===k)a=null;var h=!1;if(null===a)h=!0;else switch(k){case "string":case "number":h=!0;break;case "object":switch(a.$$typeof){case l:case n:h=!0;}}if(h)return h=a,c=c(h),a=""===d?"."+Q(h,0):d,I(c)?(e="",null!=a&&(e=a.replace(P,"$&/")+"/"),R(c,b,e,"",function(a){return a})):null!=c&&(O(c)&&(c=N(c,e+(!c.key||h&&h.key===c.key?"":(""+c.key).replace(P,"$&/")+"/")+a)),b.push(c)),1;h=0;d=""===d?".":d+":";if(I(a))for(var g=0;g<a.length;g++){k=
|
|
1693
|
-
a[g];var f=d+Q(k,g);h+=R(k,b,e,f,c);}else if(f=A(a),"function"===typeof f)for(a=f.call(a),g=0;!(k=a.next()).done;)k=k.value,f=d+Q(k,g++),h+=R(k,b,e,f,c);else if("object"===k)throw b=String(a),Error("Objects are not valid as a React child (found: "+("[object Object]"===b?"object with keys {"+Object.keys(a).join(", ")+"}":b)+"). If you meant to render a collection of children, use an array instead.");return h}
|
|
1694
|
-
function S(a,b,e){if(null==a)return a;var d=[],c=0;R(a,d,"","",function(a){return b.call(e,a,c++)});return d}function T(a){if(-1===a._status){var b=a._result;b=b();b.then(function(b){if(0===a._status||-1===a._status)a._status=1,a._result=b;},function(b){if(0===a._status||-1===a._status)a._status=2,a._result=b;});-1===a._status&&(a._status=0,a._result=b);}if(1===a._status)return a._result.default;throw a._result;}
|
|
1695
|
-
var U={current:null},V={transition:null},W={ReactCurrentDispatcher:U,ReactCurrentBatchConfig:V,ReactCurrentOwner:K};function X(){throw Error("act(...) is not supported in production builds of React.");}
|
|
1696
|
-
react_production_min.Children={map:S,forEach:function(a,b,e){S(a,function(){b.apply(this,arguments);},e);},count:function(a){var b=0;S(a,function(){b++;});return b},toArray:function(a){return S(a,function(a){return a})||[]},only:function(a){if(!O(a))throw Error("React.Children.only expected to receive a single React element child.");return a}};react_production_min.Component=E;react_production_min.Fragment=p;react_production_min.Profiler=r;react_production_min.PureComponent=G;react_production_min.StrictMode=q;react_production_min.Suspense=w;
|
|
1697
|
-
react_production_min.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=W;react_production_min.act=X;
|
|
1698
|
-
react_production_min.cloneElement=function(a,b,e){if(null===a||void 0===a)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+a+".");var d=C({},a.props),c=a.key,k=a.ref,h=a._owner;if(null!=b){void 0!==b.ref&&(k=b.ref,h=K.current);void 0!==b.key&&(c=""+b.key);if(a.type&&a.type.defaultProps)var g=a.type.defaultProps;for(f in b)J.call(b,f)&&!L.hasOwnProperty(f)&&(d[f]=void 0===b[f]&&void 0!==g?g[f]:b[f]);}var f=arguments.length-2;if(1===f)d.children=e;else if(1<f){g=Array(f);
|
|
1699
|
-
for(var m=0;m<f;m++)g[m]=arguments[m+2];d.children=g;}return {$$typeof:l,type:a.type,key:c,ref:k,props:d,_owner:h}};react_production_min.createContext=function(a){a={$$typeof:u,_currentValue:a,_currentValue2:a,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null};a.Provider={$$typeof:t,_context:a};return a.Consumer=a};react_production_min.createElement=M;react_production_min.createFactory=function(a){var b=M.bind(null,a);b.type=a;return b};react_production_min.createRef=function(){return {current:null}};
|
|
1700
|
-
react_production_min.forwardRef=function(a){return {$$typeof:v,render:a}};react_production_min.isValidElement=O;react_production_min.lazy=function(a){return {$$typeof:y,_payload:{_status:-1,_result:a},_init:T}};react_production_min.memo=function(a,b){return {$$typeof:x,type:a,compare:void 0===b?null:b}};react_production_min.startTransition=function(a){var b=V.transition;V.transition={};try{a();}finally{V.transition=b;}};react_production_min.unstable_act=X;react_production_min.useCallback=function(a,b){return U.current.useCallback(a,b)};react_production_min.useContext=function(a){return U.current.useContext(a)};
|
|
1701
|
-
react_production_min.useDebugValue=function(){};react_production_min.useDeferredValue=function(a){return U.current.useDeferredValue(a)};react_production_min.useEffect=function(a,b){return U.current.useEffect(a,b)};react_production_min.useId=function(){return U.current.useId()};react_production_min.useImperativeHandle=function(a,b,e){return U.current.useImperativeHandle(a,b,e)};react_production_min.useInsertionEffect=function(a,b){return U.current.useInsertionEffect(a,b)};react_production_min.useLayoutEffect=function(a,b){return U.current.useLayoutEffect(a,b)};
|
|
1702
|
-
react_production_min.useMemo=function(a,b){return U.current.useMemo(a,b)};react_production_min.useReducer=function(a,b,e){return U.current.useReducer(a,b,e)};react_production_min.useRef=function(a){return U.current.useRef(a)};react_production_min.useState=function(a){return U.current.useState(a)};react_production_min.useSyncExternalStore=function(a,b,e){return U.current.useSyncExternalStore(a,b,e)};react_production_min.useTransition=function(){return U.current.useTransition()};react_production_min.version="18.3.1";
|
|
1703
|
-
return react_production_min;
|
|
1704
|
-
}
|
|
1705
|
-
|
|
1706
|
-
{
|
|
1707
|
-
react.exports = requireReact_production_min();
|
|
1708
|
-
}
|
|
1709
|
-
|
|
1710
|
-
var reactExports = react.exports;
|
|
1711
|
-
|
|
1667
|
+
let globalSDKInstance = null;
|
|
1668
|
+
let isInitializing = false;
|
|
1712
1669
|
/**
|
|
1713
|
-
*
|
|
1714
|
-
* react-jsx-runtime.production.min.js
|
|
1715
|
-
*
|
|
1716
|
-
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
1717
|
-
*
|
|
1718
|
-
* This source code is licensed under the MIT license found in the
|
|
1719
|
-
* LICENSE file in the root directory of this source tree.
|
|
1670
|
+
* SDK 초기화 (한 번만 호출)
|
|
1720
1671
|
*/
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
sdk: null,
|
|
1740
|
-
isLoading: true,
|
|
1741
|
-
error: null,
|
|
1742
|
-
isInitialized: false,
|
|
1743
|
-
});
|
|
1744
|
-
const AdStageProvider = ({ config, children, autoInit = true, }) => {
|
|
1745
|
-
const [sdk, setSdk] = reactExports.useState(null);
|
|
1746
|
-
const [isLoading, setIsLoading] = reactExports.useState(true);
|
|
1747
|
-
const [error, setError] = reactExports.useState(null);
|
|
1748
|
-
const [isInitialized, setIsInitialized] = reactExports.useState(false);
|
|
1749
|
-
reactExports.useEffect(() => {
|
|
1750
|
-
const initializeSDK = async () => {
|
|
1751
|
-
try {
|
|
1752
|
-
setIsLoading(true);
|
|
1753
|
-
setError(null);
|
|
1754
|
-
// Dynamic import를 사용해서 circular dependency 방지
|
|
1755
|
-
const { AdStageSDK } = await Promise.resolve().then(function () { return index; });
|
|
1756
|
-
// SDK 인스턴스 생성
|
|
1757
|
-
const sdkInstance = AdStageSDK.init(config);
|
|
1758
|
-
setSdk(sdkInstance);
|
|
1759
|
-
setIsInitialized(true);
|
|
1760
|
-
setIsLoading(false);
|
|
1761
|
-
}
|
|
1762
|
-
catch (err) {
|
|
1763
|
-
const errorMessage = err instanceof Error ? err.message : 'SDK 초기화 중 오류가 발생했습니다.';
|
|
1764
|
-
setError(errorMessage);
|
|
1765
|
-
setIsLoading(false);
|
|
1766
|
-
console.error('AdStage SDK initialization failed:', err);
|
|
1767
|
-
}
|
|
1768
|
-
};
|
|
1769
|
-
initializeSDK();
|
|
1770
|
-
}, [config.apiKey, config.debug, autoInit]);
|
|
1771
|
-
const value = {
|
|
1772
|
-
sdk,
|
|
1773
|
-
isLoading,
|
|
1774
|
-
error,
|
|
1775
|
-
isInitialized,
|
|
1776
|
-
};
|
|
1777
|
-
return (jsxRuntimeExports.jsx(AdStageContext.Provider, { value: value, children: children }));
|
|
1778
|
-
};
|
|
1779
|
-
|
|
1780
|
-
/**
|
|
1781
|
-
* AdStage SDK 인스턴스에 접근하기 위한 Hook
|
|
1782
|
-
* AdStageProvider 내부에서만 사용 가능
|
|
1783
|
-
*/
|
|
1784
|
-
const useAdStage = () => {
|
|
1785
|
-
const context = reactExports.useContext(AdStageContext);
|
|
1786
|
-
if (!context) {
|
|
1787
|
-
throw new Error('useAdStage must be used within an AdStageProvider');
|
|
1672
|
+
async function initAdStage(config) {
|
|
1673
|
+
if (globalSDKInstance) {
|
|
1674
|
+
console.warn('AdStage SDK가 이미 초기화되었습니다.');
|
|
1675
|
+
return;
|
|
1676
|
+
}
|
|
1677
|
+
if (isInitializing) {
|
|
1678
|
+
console.warn('AdStage SDK 초기화가 진행 중입니다.');
|
|
1679
|
+
return;
|
|
1680
|
+
}
|
|
1681
|
+
isInitializing = true;
|
|
1682
|
+
try {
|
|
1683
|
+
// 동적 import로 circular dependency 방지
|
|
1684
|
+
const { AdStageSDK } = await Promise.resolve().then(function () { return index; });
|
|
1685
|
+
globalSDKInstance = AdStageSDK.init({
|
|
1686
|
+
apiKey: config.apiKey,
|
|
1687
|
+
debug: config.debug || false
|
|
1688
|
+
});
|
|
1689
|
+
console.log('✅ AdStage SDK 초기화 완료');
|
|
1788
1690
|
}
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
const containerRef = reactExports.useRef(null);
|
|
1798
|
-
const { sdk, isLoading, error } = useAdStage();
|
|
1799
|
-
const containerId = reactExports.useMemo(() => `adstage-${slotId}`, [slotId]);
|
|
1800
|
-
reactExports.useEffect(() => {
|
|
1801
|
-
if (!sdk || !containerRef.current || isLoading || error) {
|
|
1802
|
-
return;
|
|
1803
|
-
}
|
|
1804
|
-
// 컨테이너에 ID 설정
|
|
1805
|
-
containerRef.current.id = containerId;
|
|
1806
|
-
// 광고 슬롯 생성
|
|
1807
|
-
const createSlot = async () => {
|
|
1808
|
-
try {
|
|
1809
|
-
await sdk.createSlot(slotId, containerId, adType, {
|
|
1810
|
-
width,
|
|
1811
|
-
height,
|
|
1812
|
-
language,
|
|
1813
|
-
deviceType,
|
|
1814
|
-
country,
|
|
1815
|
-
autoSlideInterval,
|
|
1816
|
-
sliderEffect,
|
|
1817
|
-
});
|
|
1818
|
-
}
|
|
1819
|
-
catch (err) {
|
|
1820
|
-
console.error(`Failed to create ad slot ${slotId}:`, err);
|
|
1821
|
-
}
|
|
1822
|
-
};
|
|
1823
|
-
createSlot();
|
|
1824
|
-
// 클린업 함수
|
|
1825
|
-
return () => {
|
|
1826
|
-
// SDK에 removeSlot 메서드가 없으므로 DOM 정리만 수행
|
|
1827
|
-
if (containerRef.current) {
|
|
1828
|
-
containerRef.current.innerHTML = '';
|
|
1829
|
-
}
|
|
1830
|
-
};
|
|
1831
|
-
}, [
|
|
1832
|
-
sdk,
|
|
1833
|
-
slotId,
|
|
1834
|
-
containerId,
|
|
1835
|
-
adType,
|
|
1836
|
-
width,
|
|
1837
|
-
height,
|
|
1838
|
-
language,
|
|
1839
|
-
deviceType,
|
|
1840
|
-
country,
|
|
1841
|
-
autoSlideInterval,
|
|
1842
|
-
sliderEffect,
|
|
1843
|
-
isLoading,
|
|
1844
|
-
error,
|
|
1845
|
-
]);
|
|
1846
|
-
const containerStyle = {
|
|
1847
|
-
width: typeof width === 'number' ? `${width}px` : width,
|
|
1848
|
-
height: typeof height === 'number' ? `${height}px` : height,
|
|
1849
|
-
...style,
|
|
1850
|
-
};
|
|
1851
|
-
// 로딩 상태 표시
|
|
1852
|
-
if (isLoading) {
|
|
1853
|
-
return (jsxRuntimeExports.jsx("div", { className: className, style: {
|
|
1854
|
-
...containerStyle,
|
|
1855
|
-
display: 'flex',
|
|
1856
|
-
alignItems: 'center',
|
|
1857
|
-
justifyContent: 'center',
|
|
1858
|
-
backgroundColor: '#f5f5f5',
|
|
1859
|
-
border: '1px dashed #ccc',
|
|
1860
|
-
color: '#999',
|
|
1861
|
-
}, children: "Loading Ad..." }));
|
|
1862
|
-
}
|
|
1863
|
-
// 에러 상태 표시
|
|
1864
|
-
if (error) {
|
|
1865
|
-
return (jsxRuntimeExports.jsx("div", { className: className, style: {
|
|
1866
|
-
...containerStyle,
|
|
1867
|
-
display: 'flex',
|
|
1868
|
-
alignItems: 'center',
|
|
1869
|
-
justifyContent: 'center',
|
|
1870
|
-
backgroundColor: '#fee',
|
|
1871
|
-
border: '1px solid #fcc',
|
|
1872
|
-
color: '#c00',
|
|
1873
|
-
}, children: "Ad Load Error" }));
|
|
1874
|
-
}
|
|
1875
|
-
return (jsxRuntimeExports.jsx("div", { ref: containerRef, className: className, style: containerStyle }));
|
|
1876
|
-
};
|
|
1877
|
-
|
|
1691
|
+
catch (error) {
|
|
1692
|
+
console.error('❌ AdStage SDK 초기화 실패:', error);
|
|
1693
|
+
throw error;
|
|
1694
|
+
}
|
|
1695
|
+
finally {
|
|
1696
|
+
isInitializing = false;
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1878
1699
|
/**
|
|
1879
|
-
* 배너 광고
|
|
1880
|
-
* AdSlot의 래퍼로 adType이 BANNER로 고정됨
|
|
1700
|
+
* 배너 광고 생성 (가장 간단한 API)
|
|
1881
1701
|
*/
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1702
|
+
async function createBanner(containerId, options) {
|
|
1703
|
+
if (!globalSDKInstance) {
|
|
1704
|
+
throw new Error('AdStage SDK가 초기화되지 않았습니다. initAdStage()를 먼저 호출하세요.');
|
|
1705
|
+
}
|
|
1706
|
+
const slotId = `banner-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
1707
|
+
return globalSDKInstance.createSlot(slotId, containerId, 'BANNER', {
|
|
1708
|
+
width: options?.width || '100%',
|
|
1709
|
+
height: options?.height || 120,
|
|
1710
|
+
autoSlideInterval: options?.autoSlide ? (options.slideInterval || 5) : 0,
|
|
1711
|
+
sliderEffect: 'fade'
|
|
1712
|
+
});
|
|
1713
|
+
}
|
|
1886
1714
|
/**
|
|
1887
|
-
* 텍스트 광고
|
|
1888
|
-
* AdSlot의 래퍼로 adType이 TEXT로 고정됨
|
|
1715
|
+
* 텍스트 광고 생성
|
|
1889
1716
|
*/
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1717
|
+
async function createTextAd(containerId, options) {
|
|
1718
|
+
if (!globalSDKInstance) {
|
|
1719
|
+
throw new Error('AdStage SDK가 초기화되지 않았습니다.');
|
|
1720
|
+
}
|
|
1721
|
+
const slotId = `text-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
1722
|
+
return globalSDKInstance.createSlot(slotId, containerId, 'TEXT', {
|
|
1723
|
+
maxLines: options?.maxLines || 3,
|
|
1724
|
+
style: options?.style || 'card'
|
|
1725
|
+
});
|
|
1726
|
+
}
|
|
1894
1727
|
/**
|
|
1895
|
-
*
|
|
1896
|
-
* AdSlot의 래퍼로 adType이 NATIVE로 고정됨
|
|
1728
|
+
* 비디오 광고 생성
|
|
1897
1729
|
*/
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1730
|
+
async function createVideoAd(containerId, options) {
|
|
1731
|
+
if (!globalSDKInstance) {
|
|
1732
|
+
throw new Error('AdStage SDK가 초기화되지 않았습니다.');
|
|
1733
|
+
}
|
|
1734
|
+
const slotId = `video-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
1735
|
+
return globalSDKInstance.createSlot(slotId, containerId, 'VIDEO', {
|
|
1736
|
+
width: options?.width || '100%',
|
|
1737
|
+
height: options?.height || 300,
|
|
1738
|
+
autoplay: options?.autoplay || false,
|
|
1739
|
+
muted: options?.muted || true
|
|
1740
|
+
});
|
|
1741
|
+
}
|
|
1902
1742
|
/**
|
|
1903
|
-
*
|
|
1904
|
-
* AdSlot의 래퍼로 adType이 VIDEO로 고정됨
|
|
1743
|
+
* 커스텀 이벤트 추적
|
|
1905
1744
|
*/
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1745
|
+
function trackEvent(eventName, params) {
|
|
1746
|
+
if (!globalSDKInstance) {
|
|
1747
|
+
console.warn('AdStage SDK가 초기화되지 않았습니다. 이벤트 추적을 건너뜁니다.');
|
|
1748
|
+
return;
|
|
1749
|
+
}
|
|
1750
|
+
try {
|
|
1751
|
+
globalSDKInstance.trackEvent(eventName, {
|
|
1752
|
+
timestamp: new Date().toISOString(),
|
|
1753
|
+
...params
|
|
1754
|
+
});
|
|
1755
|
+
console.log(`📊 이벤트 추적: ${eventName}`, params);
|
|
1756
|
+
}
|
|
1757
|
+
catch (error) {
|
|
1758
|
+
console.error('이벤트 추적 실패:', error);
|
|
1759
|
+
}
|
|
1760
|
+
}
|
|
1910
1761
|
/**
|
|
1911
|
-
*
|
|
1912
|
-
* AdSlot의 래퍼로 adType이 INTERSTITIAL로 고정됨
|
|
1762
|
+
* SDK 상태 확인
|
|
1913
1763
|
*/
|
|
1914
|
-
|
|
1915
|
-
return
|
|
1916
|
-
}
|
|
1917
|
-
|
|
1764
|
+
function isAdStageReady() {
|
|
1765
|
+
return globalSDKInstance !== null && !isInitializing;
|
|
1766
|
+
}
|
|
1918
1767
|
/**
|
|
1919
|
-
*
|
|
1920
|
-
* 광고 로딩 실패 시 fallback UI를 표시하고 앱 전체가 크래시되는 것을 방지
|
|
1768
|
+
* SDK 인스턴스 가져오기 (고급 사용자용)
|
|
1921
1769
|
*/
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
}
|
|
1927
|
-
static getDerivedStateFromError(error) {
|
|
1928
|
-
return { hasError: true, error };
|
|
1929
|
-
}
|
|
1930
|
-
componentDidCatch(error, errorInfo) {
|
|
1931
|
-
console.error('AdStage Error Boundary caught an error:', error, errorInfo);
|
|
1932
|
-
// 사용자 정의 에러 핸들러 호출
|
|
1933
|
-
if (this.props.onError) {
|
|
1934
|
-
this.props.onError(error, errorInfo);
|
|
1935
|
-
}
|
|
1936
|
-
}
|
|
1937
|
-
render() {
|
|
1938
|
-
if (this.state.hasError) {
|
|
1939
|
-
// 사용자 정의 fallback이 있으면 사용, 없으면 기본 fallback 표시
|
|
1940
|
-
if (this.props.fallback) {
|
|
1941
|
-
return this.props.fallback;
|
|
1942
|
-
}
|
|
1943
|
-
return (jsxRuntimeExports.jsxs("div", { style: {
|
|
1944
|
-
padding: '20px',
|
|
1945
|
-
textAlign: 'center',
|
|
1946
|
-
backgroundColor: '#fee',
|
|
1947
|
-
border: '1px solid #fcc',
|
|
1948
|
-
borderRadius: '4px',
|
|
1949
|
-
color: '#c00',
|
|
1950
|
-
}, children: [jsxRuntimeExports.jsx("h3", { children: "\uAD11\uACE0 \uB85C\uB529 \uC624\uB958" }), jsxRuntimeExports.jsx("p", { children: "\uAD11\uACE0\uB97C \uBD88\uB7EC\uC624\uB294 \uC911 \uBB38\uC81C\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4." }), jsxRuntimeExports.jsx("button", { onClick: () => this.setState({ hasError: false, error: null }), style: {
|
|
1951
|
-
padding: '8px 16px',
|
|
1952
|
-
backgroundColor: '#fff',
|
|
1953
|
-
border: '1px solid #ccc',
|
|
1954
|
-
borderRadius: '4px',
|
|
1955
|
-
cursor: 'pointer',
|
|
1956
|
-
}, children: "\uB2E4\uC2DC \uC2DC\uB3C4" })] }));
|
|
1957
|
-
}
|
|
1958
|
-
return this.props.children;
|
|
1770
|
+
function getAdStageInstance() {
|
|
1771
|
+
if (!globalSDKInstance) {
|
|
1772
|
+
console.warn('AdStage SDK가 초기화되지 않았습니다.');
|
|
1773
|
+
return null;
|
|
1959
1774
|
}
|
|
1775
|
+
return globalSDKInstance;
|
|
1960
1776
|
}
|
|
1961
|
-
|
|
1962
1777
|
/**
|
|
1963
|
-
*
|
|
1964
|
-
* 컴포넌트에서 직접 슬롯을 제어하고 싶을 때 사용
|
|
1778
|
+
* SDK 초기화 해제 (필요시)
|
|
1965
1779
|
*/
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
const [isLoading, setIsLoading] = reactExports.useState(false);
|
|
1969
|
-
const [error, setError] = reactExports.useState(null);
|
|
1970
|
-
const [isCreated, setIsCreated] = reactExports.useState(false);
|
|
1971
|
-
const createSlot = async () => {
|
|
1972
|
-
if (!sdk) {
|
|
1973
|
-
setError('SDK not initialized');
|
|
1974
|
-
return;
|
|
1975
|
-
}
|
|
1976
|
-
setIsLoading(true);
|
|
1977
|
-
setError(null);
|
|
1780
|
+
function destroyAdStage() {
|
|
1781
|
+
if (globalSDKInstance) {
|
|
1978
1782
|
try {
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
language: options.language,
|
|
1983
|
-
deviceType: options.deviceType,
|
|
1984
|
-
country: options.country,
|
|
1985
|
-
autoSlideInterval: options.autoSlideInterval,
|
|
1986
|
-
sliderEffect: options.sliderEffect,
|
|
1987
|
-
});
|
|
1988
|
-
setIsCreated(true);
|
|
1989
|
-
}
|
|
1990
|
-
catch (err) {
|
|
1991
|
-
const errorMessage = err instanceof Error ? err.message : '슬롯 생성 중 오류가 발생했습니다.';
|
|
1992
|
-
setError(errorMessage);
|
|
1993
|
-
setIsCreated(false);
|
|
1994
|
-
}
|
|
1995
|
-
finally {
|
|
1996
|
-
setIsLoading(false);
|
|
1997
|
-
}
|
|
1998
|
-
};
|
|
1999
|
-
const resetSlot = () => {
|
|
2000
|
-
setIsLoading(false);
|
|
2001
|
-
setError(null);
|
|
2002
|
-
setIsCreated(false);
|
|
2003
|
-
};
|
|
2004
|
-
// SDK가 변경되면 상태 초기화
|
|
2005
|
-
reactExports.useEffect(() => {
|
|
2006
|
-
resetSlot();
|
|
2007
|
-
}, [sdk]);
|
|
2008
|
-
return {
|
|
2009
|
-
isLoading,
|
|
2010
|
-
error,
|
|
2011
|
-
isCreated,
|
|
2012
|
-
createSlot,
|
|
2013
|
-
resetSlot,
|
|
2014
|
-
};
|
|
2015
|
-
};
|
|
2016
|
-
|
|
2017
|
-
/**
|
|
2018
|
-
* 광고 이벤트 추적을 위한 Hook
|
|
2019
|
-
* 커스텀 이벤트 추적이 필요할 때 사용
|
|
2020
|
-
*/
|
|
2021
|
-
const useAdTracking = () => {
|
|
2022
|
-
const { sdk } = useAdStage();
|
|
2023
|
-
const trackEvent = reactExports.useCallback((adId, slotId, eventType) => {
|
|
2024
|
-
if (!sdk) {
|
|
2025
|
-
console.warn('SDK not initialized - cannot track event');
|
|
2026
|
-
return;
|
|
1783
|
+
// SDK cleanup logic here
|
|
1784
|
+
globalSDKInstance = null;
|
|
1785
|
+
console.log('🧹 AdStage SDK 정리 완료');
|
|
2027
1786
|
}
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
// sdk.trackEvent(adId, slotId, eventType);
|
|
2034
|
-
}
|
|
2035
|
-
catch (err) {
|
|
2036
|
-
console.error('Failed to track event:', err);
|
|
2037
|
-
}
|
|
2038
|
-
}, [sdk]);
|
|
2039
|
-
const trackClick = reactExports.useCallback((adId, slotId) => {
|
|
2040
|
-
trackEvent(adId, slotId, AdEventType.CLICK);
|
|
2041
|
-
}, [trackEvent]);
|
|
2042
|
-
const trackImpression = reactExports.useCallback((adId, slotId) => {
|
|
2043
|
-
trackEvent(adId, slotId, AdEventType.IMPRESSION);
|
|
2044
|
-
}, [trackEvent]);
|
|
2045
|
-
const trackView = reactExports.useCallback((adId, slotId) => {
|
|
2046
|
-
trackEvent(adId, slotId, AdEventType.VIEWABLE);
|
|
2047
|
-
}, [trackEvent]);
|
|
2048
|
-
const trackClose = reactExports.useCallback((adId, slotId) => {
|
|
2049
|
-
trackEvent(adId, slotId, AdEventType.COMPLETED);
|
|
2050
|
-
}, [trackEvent]);
|
|
2051
|
-
return {
|
|
2052
|
-
trackEvent,
|
|
2053
|
-
trackClick,
|
|
2054
|
-
trackImpression,
|
|
2055
|
-
trackView,
|
|
2056
|
-
trackClose,
|
|
2057
|
-
};
|
|
2058
|
-
};
|
|
1787
|
+
catch (error) {
|
|
1788
|
+
console.error('SDK 정리 중 오류:', error);
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
2059
1792
|
|
|
2060
1793
|
/**
|
|
2061
1794
|
* AdStage SDK 메인 클래스
|
|
@@ -2308,24 +2041,23 @@ if (DOMUtils.isBrowser()) {
|
|
|
2308
2041
|
DOMUtils.waitForDOM().then(autoInit);
|
|
2309
2042
|
}
|
|
2310
2043
|
}
|
|
2044
|
+
// React exports (React가 있을 때만 사용 - 레거시)
|
|
2045
|
+
// export * from './react';
|
|
2311
2046
|
|
|
2312
2047
|
var index = /*#__PURE__*/Object.freeze({
|
|
2313
2048
|
__proto__: null,
|
|
2314
|
-
AdErrorBoundary: AdErrorBoundary,
|
|
2315
2049
|
get AdEventType () { return AdEventType; },
|
|
2316
|
-
AdSlot: AdSlot,
|
|
2317
|
-
AdStageProvider: AdStageProvider,
|
|
2318
2050
|
AdStageSDK: AdStageSDK,
|
|
2319
2051
|
get AdType () { return AdType; },
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
TextAd: TextAd,
|
|
2324
|
-
VideoAd: VideoAd,
|
|
2052
|
+
createBanner: createBanner,
|
|
2053
|
+
createTextAd: createTextAd,
|
|
2054
|
+
createVideoAd: createVideoAd,
|
|
2325
2055
|
default: AdStageSDK,
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2056
|
+
destroyAdStage: destroyAdStage,
|
|
2057
|
+
getAdStageInstance: getAdStageInstance,
|
|
2058
|
+
initAdStage: initAdStage,
|
|
2059
|
+
isAdStageReady: isAdStageReady,
|
|
2060
|
+
trackEvent: trackEvent
|
|
2329
2061
|
});
|
|
2330
2062
|
|
|
2331
|
-
export {
|
|
2063
|
+
export { AdEventType, AdStageSDK, AdType, createBanner, createTextAd, createVideoAd, AdStageSDK as default, destroyAdStage, getAdStageInstance, initAdStage, isAdStageReady, trackEvent };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adstage/web-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "AdStage Web SDK for displaying advertisements",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs.js",
|
|
@@ -62,7 +62,6 @@
|
|
|
62
62
|
"@rollup/plugin-typescript": "^11.1.0",
|
|
63
63
|
"@types/node": "^20.0.0",
|
|
64
64
|
"@types/react": "^18.0.0",
|
|
65
|
-
"react": "^18.0.0",
|
|
66
65
|
"rollup": "^3.23.0",
|
|
67
66
|
"rollup-plugin-dts": "^5.3.0",
|
|
68
67
|
"tslib": "^2.8.1",
|
|
@@ -71,6 +70,11 @@
|
|
|
71
70
|
"peerDependencies": {
|
|
72
71
|
"react": ">=16.8.0"
|
|
73
72
|
},
|
|
73
|
+
"peerDependenciesMeta": {
|
|
74
|
+
"react": {
|
|
75
|
+
"optional": true
|
|
76
|
+
}
|
|
77
|
+
},
|
|
74
78
|
"repository": {
|
|
75
79
|
"type": "git",
|
|
76
80
|
"url": "https://github.com/nbase-io/adstage.git",
|
package/src/index.ts
CHANGED
|
@@ -346,5 +346,8 @@ export default AdStageSDK;
|
|
|
346
346
|
export { AdType, AdEventType };
|
|
347
347
|
export type { AdSlot, Advertisement };
|
|
348
348
|
|
|
349
|
-
//
|
|
350
|
-
export * from './
|
|
349
|
+
// Standalone API (추천 사용법)
|
|
350
|
+
export * from './utils/sdk-standalone';
|
|
351
|
+
|
|
352
|
+
// React exports (React가 있을 때만 사용 - 레거시)
|
|
353
|
+
// export * from './react';
|