@ad-execute-manager/core 2.0.2 → 2.0.4
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/dist/AdExecuteManager.d.ts +30 -2
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/typings/ad.d.ts +15 -5
- package/package.json +2 -2
|
@@ -90,6 +90,32 @@ export type IConstructArgs = {
|
|
|
90
90
|
*/
|
|
91
91
|
errorRetryStrategy?: ErrorRetryStrategy;
|
|
92
92
|
};
|
|
93
|
+
export type ITaskResult = {
|
|
94
|
+
/**
|
|
95
|
+
* 广告任务的唯一标识符
|
|
96
|
+
*/
|
|
97
|
+
id: string;
|
|
98
|
+
/**
|
|
99
|
+
* 广告错误信息
|
|
100
|
+
*/
|
|
101
|
+
apiError?: import("./typings/ad.js").IApiError;
|
|
102
|
+
/**
|
|
103
|
+
* 广告任务后台恢复前台时预估重试次数的原因
|
|
104
|
+
*/
|
|
105
|
+
recovered?: import("./typings/ad.js").RecoveredInfo;
|
|
106
|
+
/**
|
|
107
|
+
* 广告场景
|
|
108
|
+
*/
|
|
109
|
+
scene?: string;
|
|
110
|
+
/**
|
|
111
|
+
* 广告类型 1:激励视频 2:插屏
|
|
112
|
+
*/
|
|
113
|
+
adTypeR?: 1 | 2;
|
|
114
|
+
/**
|
|
115
|
+
* 广告结束类型
|
|
116
|
+
*/
|
|
117
|
+
end_type?: "finished" | "halfway";
|
|
118
|
+
};
|
|
93
119
|
declare class AdExecuteManager {
|
|
94
120
|
/**
|
|
95
121
|
* 单例实例
|
|
@@ -212,12 +238,14 @@ declare class AdExecuteManager {
|
|
|
212
238
|
* @param {Object} ctx 广告执行上下文
|
|
213
239
|
* @param {IRewordAdConfig} ctx.options 广告执行选项
|
|
214
240
|
* @param {CallbackCollection} ctx.collection 回调集合
|
|
215
|
-
* @returns {Promise} 广告执行结果的Promise
|
|
241
|
+
* @returns {Promise.<ITaskResult & {[key: string]: any}> | Undefined>} 广告执行结果的Promise
|
|
216
242
|
*/
|
|
217
243
|
addTask(adInstance: IAdInstance, ctx: {
|
|
218
244
|
options: IRewordAdConfig;
|
|
219
245
|
collection: CallbackCollection;
|
|
220
|
-
}): Promise<
|
|
246
|
+
}): Promise<ITaskResult & {
|
|
247
|
+
[key: string]: any;
|
|
248
|
+
}> | undefined;
|
|
221
249
|
/**
|
|
222
250
|
* 组合所有任务
|
|
223
251
|
* @private
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const __rslib_import_meta_url__="u"<typeof document?new(require("url".replace("",""))).URL("file:"+__filename).href:document.currentScript&&document.currentScript.src||new URL("main.js",document.baseURI).href;var __webpack_require__={};__webpack_require__.d=(e,t)=>{for(var r in t)__webpack_require__.o(t,r)&&!__webpack_require__.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var __webpack_exports__={};__webpack_require__.r(__webpack_exports__),__webpack_require__.d(__webpack_exports__,{AdExecuteManager:()=>src_AdExecuteManager});const logger_namespaceObject=require("@ad-execute-manager/logger");function isTimeoutError(e,t){return(null==e?void 0:e.errMsg)&&"string"==typeof e.errMsg&&e.errMsg.startsWith("ad_show_timeout: normal")&&(null==e?void 0:e.timeout)==t}function isBackgroundError(e){return(null==e?void 0:e.errMsg)&&"string"==typeof e.errMsg&&(e.errMsg.startsWith("app in background is not support show ad")||e.errMsg.startsWith("other controller is presented"))}function needRetryAdError({apiError:e,configuredAdTimeout:t,errorRetryStrategy:r}){return!!((null==r?void 0:r.timeout)&&isTimeoutError(e,t)||(null==r?void 0:r.background)&&isBackgroundError(e))}const compose=e=>e.map(e=>(t,r)=>async i=>await e(Object.assign({},t,i),r)).reduce((e,t)=>(r,i)=>e(r,t(r,i))),src_compose=compose;class AdExecuteManager{static _instance=null;_taskStack=[];_currentBatchTasks=[];_isRunning=!1;_currentTask=null;_isForeground=!0;_appShowListener=null;_appHideListener=null;_enableVisibilityListener=!1;_maxRetryCount=1;_retryQueue=[];_errorRetryStrategy={timeout:!0,background:!0};constructor(e){this.logger=new logger_namespaceObject.Logger({prefix:"AdExecuteManager",enabled:!!(null==e?void 0:e.log)}),(null==e?void 0:e.errorRetryStrategy)&&(this._errorRetryStrategy=Object.assign({},this._errorRetryStrategy,null==e?void 0:e.errorRetryStrategy)),this._enableVisibilityListener=null==e?void 0:e.enableVisibilityListener,this._maxRetryCount=(null==e?void 0:e.maxRetryCount)??1,this._enableVisibilityListener&&this._initVisibilityListener()}initialize(e){return this}static getInstance(e){return AdExecuteManager._instance||(AdExecuteManager._instance=new AdExecuteManager(e)),AdExecuteManager._instance}static build(e){return AdExecuteManager._instance||(AdExecuteManager._instance=new AdExecuteManager(e)),AdExecuteManager._instance}static new(e){return new AdExecuteManager(e)}static getSafeInstance(){return AdExecuteManager._instance?AdExecuteManager._instance:(this.logger.error("AdExecuteManager实例不存在"),null)}_initVisibilityListener(){!("u"<typeof tt)&&tt.onAppShow&&tt.onAppHide?(this._appShowListener=()=>{this._isForeground=!0,this._handleAppShow()},this._appHideListener=()=>{this._isForeground=!1,this._handleAppHide()},tt.onAppShow(this._appShowListener),tt.onAppHide(this._appHideListener),this.logger.info("前后台监听器已初始化")):this.logger.warn("tt API不可用,无法监听前后台状态")}_handleAppHide(){if(this._isRunning&&this._currentBatchTasks.length>0){let e=this._currentBatchTasks.filter(e=>{var t;return e.id!==(null==(t=this._currentTask)?void 0:t.id)&&!e._isResolved&&!e._isRejected});e.length>0&&(this.logger.info(`将 ${e.length} 个未执行的任务放回任务栈,任务ID: ${e.map(e=>e.id).join(",")}`),this._taskStack=[...e,...this._taskStack],this._currentBatchTasks=this._currentBatchTasks.filter(t=>!e.some(e=>e.id===t.id)))}}_handleAppShow(){this._retryQueue.length>0&&(this.logger.info(`应用进入前台:优先执行重试队列,任务数: ${this._retryQueue.length}, 任务ID: ${this._retryQueue.map(e=>e.id).join(",")}`),this._taskStack=[...this._retryQueue,...this._taskStack],this._retryQueue=[]),this._taskStack.length>0&&!this._isRunning&&(this.logger.info(`应用进入前台:恢复待执行任务数: ${this._taskStack.length}, 任务ID: ${this._taskStack.map(e=>e.id).join(",")}`),this._compose())}destroyVisibilityListener(){this._appShowListener&&"u">typeof tt&&tt.offAppShow&&(tt.offAppShow(this._appShowListener),this._appShowListener=null),this._appHideListener&&"u">typeof tt&&tt.offAppHide&&(tt.offAppHide(this._appHideListener),this._appHideListener=null),this.logger.info("前后台监听器已销毁")}enableVisibilityListener(){this._enableVisibilityListener||(this._enableVisibilityListener=!0,this._initVisibilityListener()),this.logger.info("前后台监听器已启用")}disableVisibilityListener(){this._enableVisibilityListener&&(this._enableVisibilityListener=!1,this.destroyVisibilityListener()),this.logger.info("前后台监听器已禁用")}isVisibilityListenerEnabled(){return this._enableVisibilityListener}addTask(e,t){return e&&"function"==typeof e.ad?new Promise((r,i)=>{let s={adInstance:e,options:t.options??{},callbackCollection:t.collection??{},resolve:r,reject:i,id:`ad_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,_isResolved:!1,_isRejected:!1,_retryCount:0,_retryMsg:"ok"};this._taskStack.push(s),this._isRunning||this._compose()}):(this.logger.error("无效的广告实例 请正确实现.ad方法"),Promise.reject(Error("无效的广告实例")))}_compose(){if(0===this._taskStack.length){this._isRunning=!1,this._currentTask=null;return}if(!this._isForeground){this.logger.info(`应用处于后台,暂停任务执行,任务ID: ${this._taskStack.map(e=>e.id).join(",")}`),this._isRunning=!1;return}this._isRunning=!0;let e=[...this._taskStack];this._taskStack=[],this._currentBatchTasks=e;let t=e.map(e=>async(t,r)=>{let{adInstance:i,options:s,callbackCollection:n,resolve:a,id:o,_retryCount:c,_retryMsg:l}=e,_={count:c,retry:c>0,message:l};if(e._isResolved||e._isRejected)return void await r(t);this._currentTask=e;try{let c=async e=>{await r(Object.assign({},t,e))},l=await i.initialize(s).ad({options:s,collection:n,recovered:_},c),h=Object.assign({id:o,recovered:_},l);if(this.logger.info(`任务执行成功,成功信息:${JSON.stringify(h)}`),needRetryAdError({apiError:null==h?void 0:h.apiError,configuredAdTimeout:i._adTimeoutTime,errorRetryStrategy:this._errorRetryStrategy})&&!this._isForeground&&e._retryCount<this._maxRetryCount){var u;e._retryCount++,e._retryMsg=(null==h||null==(u=h.apiError)?void 0:u.errMsg)||"unknown";let t=`任务 ${o} 在后台失败,加入重试队列 (即将第 ${e._retryCount} 次重试, 最大重试次数 ${this._maxRetryCount}, 重试原因: ${e._retryMsg})`;this.logger.warn(t),h.recovered.retry=!0,h.recovered.count=e._retryCount,h.recovered.message=e._retryMsg,e._isResolved=!1,e._isRejected=!1,this._retryQueue.push(e)}else e._isResolved=!0;a(h),null==i||i.record(h)}catch(n){let s=Object.assign({id:o,apiError:n,recovered:_});this.logger.error(`任务执行失败, 继续下一个任务,错误信息:${JSON.stringify(s)}`),e._isRejected=!0;try{null==i||i.clear()}catch(e){this.logger.error("clear error: ",JSON.stringify(Object.assign({id:o,apiError:e})))}a(s),null==i||i.record(s),await r(t)}}),r={roundTasks:t.length};compose(t)(r,async e=>{this.logger.info("本轮活动队列已经清空",e),this._taskStack.length>0?Promise.resolve().then(()=>{this._compose()}):(this._isRunning=!1,this._currentTask=null,this._currentBatchTasks=[])})()}clearTasks(){if(this._currentTask){if(this._currentTask._isResolved||this._currentTask._isRejected){this._currentTask=null;return}try{this._currentTask.callbackCollection&&this._currentTask.callbackCollection.
|
|
1
|
+
"use strict";const __rslib_import_meta_url__="u"<typeof document?new(require("url".replace("",""))).URL("file:"+__filename).href:document.currentScript&&document.currentScript.src||new URL("main.js",document.baseURI).href;var __webpack_require__={};__webpack_require__.d=(e,t)=>{for(var r in t)__webpack_require__.o(t,r)&&!__webpack_require__.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var __webpack_exports__={};__webpack_require__.r(__webpack_exports__),__webpack_require__.d(__webpack_exports__,{AdExecuteManager:()=>src_AdExecuteManager});const logger_namespaceObject=require("@ad-execute-manager/logger");function isTimeoutError(e,t){return(null==e?void 0:e.errMsg)&&"string"==typeof e.errMsg&&e.errMsg.startsWith("ad_show_timeout: normal")&&(null==e?void 0:e.timeout)==t}function isBackgroundError(e){return(null==e?void 0:e.errMsg)&&"string"==typeof e.errMsg&&(e.errMsg.startsWith("app in background is not support show ad")||e.errMsg.startsWith("other controller is presented"))}function needRetryAdError({apiError:e,configuredAdTimeout:t,errorRetryStrategy:r}){return!!((null==r?void 0:r.timeout)&&isTimeoutError(e,t)||(null==r?void 0:r.background)&&isBackgroundError(e))}const compose=e=>e.map(e=>(t,r)=>async i=>await e(Object.assign({},t,i),r)).reduce((e,t)=>(r,i)=>e(r,t(r,i))),src_compose=compose;class AdExecuteManager{static _instance=null;_taskStack=[];_currentBatchTasks=[];_isRunning=!1;_currentTask=null;_isForeground=!0;_appShowListener=null;_appHideListener=null;_enableVisibilityListener=!1;_maxRetryCount=1;_retryQueue=[];_errorRetryStrategy={timeout:!0,background:!0};constructor(e){this.logger=new logger_namespaceObject.Logger({prefix:"AdExecuteManager",enabled:!!(null==e?void 0:e.log)}),(null==e?void 0:e.errorRetryStrategy)&&(this._errorRetryStrategy=Object.assign({},this._errorRetryStrategy,null==e?void 0:e.errorRetryStrategy)),this._enableVisibilityListener=null==e?void 0:e.enableVisibilityListener,this._maxRetryCount=(null==e?void 0:e.maxRetryCount)??1,this._enableVisibilityListener&&this._initVisibilityListener()}initialize(e){return this}static getInstance(e){return AdExecuteManager._instance||(AdExecuteManager._instance=new AdExecuteManager(e)),AdExecuteManager._instance}static build(e){return AdExecuteManager._instance||(AdExecuteManager._instance=new AdExecuteManager(e)),AdExecuteManager._instance}static new(e){return new AdExecuteManager(e)}static getSafeInstance(){return AdExecuteManager._instance?AdExecuteManager._instance:(this.logger.error("AdExecuteManager实例不存在"),null)}_initVisibilityListener(){!("u"<typeof tt)&&tt.onAppShow&&tt.onAppHide?(this._appShowListener=()=>{this._isForeground=!0,this._handleAppShow()},this._appHideListener=()=>{this._isForeground=!1,this._handleAppHide()},tt.onAppShow(this._appShowListener),tt.onAppHide(this._appHideListener),this.logger.info("前后台监听器已初始化")):this.logger.warn("tt API不可用,无法监听前后台状态")}_handleAppHide(){if(this._isRunning&&this._currentBatchTasks.length>0){let e=this._currentBatchTasks.filter(e=>{var t;return e.id!==(null==(t=this._currentTask)?void 0:t.id)&&!e._isResolved&&!e._isRejected});e.length>0&&(this.logger.info(`将 ${e.length} 个未执行的任务放回任务栈,任务ID: ${e.map(e=>e.id).join(",")}`),this._taskStack=[...e,...this._taskStack],this._currentBatchTasks=this._currentBatchTasks.filter(t=>!e.some(e=>e.id===t.id)))}}_handleAppShow(){this._retryQueue.length>0&&(this.logger.info(`应用进入前台:优先执行重试队列,任务数: ${this._retryQueue.length}, 任务ID: ${this._retryQueue.map(e=>e.id).join(",")}`),this._taskStack=[...this._retryQueue,...this._taskStack],this._retryQueue=[]),this._taskStack.length>0&&!this._isRunning&&(this.logger.info(`应用进入前台:恢复待执行任务数: ${this._taskStack.length}, 任务ID: ${this._taskStack.map(e=>e.id).join(",")}`),this._compose())}destroyVisibilityListener(){this._appShowListener&&"u">typeof tt&&tt.offAppShow&&(tt.offAppShow(this._appShowListener),this._appShowListener=null),this._appHideListener&&"u">typeof tt&&tt.offAppHide&&(tt.offAppHide(this._appHideListener),this._appHideListener=null),this.logger.info("前后台监听器已销毁")}enableVisibilityListener(){this._enableVisibilityListener||(this._enableVisibilityListener=!0,this._initVisibilityListener()),this.logger.info("前后台监听器已启用")}disableVisibilityListener(){this._enableVisibilityListener&&(this._enableVisibilityListener=!1,this.destroyVisibilityListener()),this.logger.info("前后台监听器已禁用")}isVisibilityListenerEnabled(){return this._enableVisibilityListener}addTask(e,t){return e&&"function"==typeof e.ad?new Promise((r,i)=>{let s={adInstance:e,options:t.options??{},callbackCollection:t.collection??{},resolve:r,reject:i,id:`ad_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,_isResolved:!1,_isRejected:!1,_retryCount:0,_retryMsg:"ok"};this._taskStack.push(s),this._isRunning||this._compose()}):(this.logger.error("无效的广告实例 请正确实现.ad方法"),Promise.reject(Error("无效的广告实例")))}_compose(){if(0===this._taskStack.length){this._isRunning=!1,this._currentTask=null;return}if(!this._isForeground){this.logger.info(`应用处于后台,暂停任务执行,任务ID: ${this._taskStack.map(e=>e.id).join(",")}`),this._isRunning=!1;return}this._isRunning=!0;let e=[...this._taskStack];this._taskStack=[],this._currentBatchTasks=e;let t=e.map(e=>async(t,r)=>{let{adInstance:i,options:s,callbackCollection:n,resolve:a,id:o,_retryCount:c,_retryMsg:l}=e,_={count:c,retry:c>0,message:l};if(e._isResolved||e._isRejected)return void await r(t);this._currentTask=e;try{let c=async e=>{await r(Object.assign({},t,e))},l=await i.initialize(s).ad({options:s,collection:n,recovered:_},c),h=Object.assign({id:o,recovered:_},l);if(this.logger.info(`任务执行成功,成功信息:${JSON.stringify(h)}`),needRetryAdError({apiError:null==h?void 0:h.apiError,configuredAdTimeout:i._adTimeoutTime,errorRetryStrategy:this._errorRetryStrategy})&&!this._isForeground&&e._retryCount<this._maxRetryCount){var u;e._retryCount++,e._retryMsg=(null==h||null==(u=h.apiError)?void 0:u.errMsg)||"unknown";let t=`任务 ${o} 在后台失败,加入重试队列 (即将第 ${e._retryCount} 次重试, 最大重试次数 ${this._maxRetryCount}, 重试原因: ${e._retryMsg})`;this.logger.warn(t),h.recovered.retry=!0,h.recovered.count=e._retryCount,h.recovered.message=e._retryMsg,e._isResolved=!1,e._isRejected=!1,this._retryQueue.push(e)}else e._isResolved=!0;a(h),null==i||i.record(h)}catch(n){let s=Object.assign({id:o,apiError:n,recovered:_});this.logger.error(`任务执行失败, 继续下一个任务,错误信息:${JSON.stringify(s)}`),e._isRejected=!0;try{null==i||i.clear()}catch(e){this.logger.error("clear error: ",JSON.stringify(Object.assign({id:o,apiError:e})))}a(s),null==i||i.record(s),await r(t)}}),r={roundTasks:t.length};compose(t)(r,async e=>{this.logger.info("本轮活动队列已经清空",e),this._taskStack.length>0?Promise.resolve().then(()=>{this._compose()}):(this._isRunning=!1,this._currentTask=null,this._currentBatchTasks=[])})()}clearTasks(){if(this._currentTask){if(this._currentTask._isResolved||this._currentTask._isRejected){this._currentTask=null;return}try{this._currentTask.callbackCollection&&this._currentTask.callbackCollection.cancel&&this._currentTask.callbackCollection.cancel(),this._currentTask._isResolved=!0,this._currentTask.resolve()}catch(e){this.logger.error("clear current task error: ",e)}this._currentTask=null}this._currentBatchTasks.length>0&&(this._currentBatchTasks.forEach(e=>{if(e!==this._currentTask&&!e._isResolved&&!e._isRejected)try{e.callbackCollection&&e.callbackCollection.cancel&&e.callbackCollection.cancel(),e._isResolved=!0,e.resolve()}catch(e){this.logger.error("clear current batch task error: ",e)}}),this._currentBatchTasks=[]),this._taskStack.forEach(e=>{if(!e._isResolved&&!e._isRejected&&(e._isResolved=!0,e.resolve(),e.callbackCollection&&e.callbackCollection.cancel))try{e.callbackCollection.cancel()}catch(e){this.logger.error("clear task error: ",e)}}),this._retryQueue.forEach(e=>{if(!e._isResolved&&!e._isRejected&&(e._isResolved=!0,e.resolve(),e.callbackCollection&&e.callbackCollection.cancel))try{e.callbackCollection.cancel()}catch(e){this.logger.error("clear retry task error: ",e)}}),this._taskStack=[],this._retryQueue=[],this._isRunning=!1}getTaskCount(){return this._taskStack.filter(e=>!e._isResolved&&!e._isRejected).length+this._currentBatchTasks.filter(e=>e!==this._currentTask&&!e._isResolved&&!e._isRejected).length+(!this._currentTask||this._currentTask._isResolved||this._currentTask._isRejected?0:1)+this._retryQueue.filter(e=>!e._isResolved&&!e._isRejected).length}isRunning(){return this._isRunning}getCurrentTaskId(){var e;return(null==(e=this._currentTask)?void 0:e.id)||null}whenAllTasksComplete(){return new Promise(e=>{let t=null,r=()=>{let i=0===this._taskStack.length,s=!this._isRunning,n=null===this._currentTask,a=0===this._currentBatchTasks.length||this._currentBatchTasks.every(e=>e._isResolved||e._isRejected),o=0===this._retryQueue.length;i&&s&&n&&a&&o?(t&&clearTimeout(t),e()):t=setTimeout(r,500)};r()})}}const src_AdExecuteManager=AdExecuteManager;for(var __rspack_i in exports.AdExecuteManager=__webpack_exports__.AdExecuteManager,__webpack_exports__)-1===["AdExecuteManager"].indexOf(__rspack_i)&&(exports[__rspack_i]=__webpack_exports__[__rspack_i]);Object.defineProperty(exports,"__esModule",{value:!0});
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Logger as e}from"@ad-execute-manager/logger";class t{static _instance=null;_taskStack=[];_currentBatchTasks=[];_isRunning=!1;_currentTask=null;_isForeground=!0;_appShowListener=null;_appHideListener=null;_enableVisibilityListener=!1;_maxRetryCount=1;_retryQueue=[];_errorRetryStrategy={timeout:!0,background:!0};constructor(t){this.logger=new e({prefix:"AdExecuteManager",enabled:!!(null==t?void 0:t.log)}),(null==t?void 0:t.errorRetryStrategy)&&(this._errorRetryStrategy=Object.assign({},this._errorRetryStrategy,null==t?void 0:t.errorRetryStrategy)),this._enableVisibilityListener=null==t?void 0:t.enableVisibilityListener,this._maxRetryCount=(null==t?void 0:t.maxRetryCount)??1,this._enableVisibilityListener&&this._initVisibilityListener()}initialize(e){return this}static getInstance(e){return t._instance||(t._instance=new t(e)),t._instance}static build(e){return t._instance||(t._instance=new t(e)),t._instance}static new(e){return new t(e)}static getSafeInstance(){return t._instance?t._instance:(this.logger.error("AdExecuteManager实例不存在"),null)}_initVisibilityListener(){!("u"<typeof tt)&&tt.onAppShow&&tt.onAppHide?(this._appShowListener=()=>{this._isForeground=!0,this._handleAppShow()},this._appHideListener=()=>{this._isForeground=!1,this._handleAppHide()},tt.onAppShow(this._appShowListener),tt.onAppHide(this._appHideListener),this.logger.info("前后台监听器已初始化")):this.logger.warn("tt API不可用,无法监听前后台状态")}_handleAppHide(){if(this._isRunning&&this._currentBatchTasks.length>0){let e=this._currentBatchTasks.filter(e=>{var t;return e.id!==(null==(t=this._currentTask)?void 0:t.id)&&!e._isResolved&&!e._isRejected});e.length>0&&(this.logger.info(`将 ${e.length} 个未执行的任务放回任务栈,任务ID: ${e.map(e=>e.id).join(",")}`),this._taskStack=[...e,...this._taskStack],this._currentBatchTasks=this._currentBatchTasks.filter(t=>!e.some(e=>e.id===t.id)))}}_handleAppShow(){this._retryQueue.length>0&&(this.logger.info(`应用进入前台:优先执行重试队列,任务数: ${this._retryQueue.length}, 任务ID: ${this._retryQueue.map(e=>e.id).join(",")}`),this._taskStack=[...this._retryQueue,...this._taskStack],this._retryQueue=[]),this._taskStack.length>0&&!this._isRunning&&(this.logger.info(`应用进入前台:恢复待执行任务数: ${this._taskStack.length}, 任务ID: ${this._taskStack.map(e=>e.id).join(",")}`),this._compose())}destroyVisibilityListener(){this._appShowListener&&"u">typeof tt&&tt.offAppShow&&(tt.offAppShow(this._appShowListener),this._appShowListener=null),this._appHideListener&&"u">typeof tt&&tt.offAppHide&&(tt.offAppHide(this._appHideListener),this._appHideListener=null),this.logger.info("前后台监听器已销毁")}enableVisibilityListener(){this._enableVisibilityListener||(this._enableVisibilityListener=!0,this._initVisibilityListener()),this.logger.info("前后台监听器已启用")}disableVisibilityListener(){this._enableVisibilityListener&&(this._enableVisibilityListener=!1,this.destroyVisibilityListener()),this.logger.info("前后台监听器已禁用")}isVisibilityListenerEnabled(){return this._enableVisibilityListener}addTask(e,t){return e&&"function"==typeof e.ad?new Promise((i,r)=>{let s={adInstance:e,options:t.options??{},callbackCollection:t.collection??{},resolve:i,reject:r,id:`ad_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,_isResolved:!1,_isRejected:!1,_retryCount:0,_retryMsg:"ok"};this._taskStack.push(s),this._isRunning||this._compose()}):(this.logger.error("无效的广告实例 请正确实现.ad方法"),Promise.reject(Error("无效的广告实例")))}_compose(){if(0===this._taskStack.length){this._isRunning=!1,this._currentTask=null;return}if(!this._isForeground){this.logger.info(`应用处于后台,暂停任务执行,任务ID: ${this._taskStack.map(e=>e.id).join(",")}`),this._isRunning=!1;return}this._isRunning=!0;let e=[...this._taskStack];this._taskStack=[],this._currentBatchTasks=e;let t=e.map(e=>async(t,i)=>{let{adInstance:r,options:s,callbackCollection:n,resolve:a,id:l,_retryCount:o,_retryMsg:c}=e,h={count:o,retry:o>0,message:c};if(e._isResolved||e._isRejected)return void await i(t);this._currentTask=e;try{let o=async e=>{await i(Object.assign({},t,e))},c=await r.initialize(s).ad({options:s,collection:n,recovered:h},o),u=Object.assign({id:l,recovered:h},c);if(this.logger.info(`任务执行成功,成功信息:${JSON.stringify(u)}`),function({apiError:e,configuredAdTimeout:t,errorRetryStrategy:i}){var r;return!!((null==i?void 0:i.timeout)&&(null==e?void 0:e.errMsg)&&"string"==typeof e.errMsg&&e.errMsg.startsWith("ad_show_timeout: normal")&&(null==e?void 0:e.timeout)==t)||!!((null==i?void 0:i.background)&&(null==(r=e)?void 0:r.errMsg)&&"string"==typeof r.errMsg&&(r.errMsg.startsWith("app in background is not support show ad")||r.errMsg.startsWith("other controller is presented")))}({apiError:null==u?void 0:u.apiError,configuredAdTimeout:r._adTimeoutTime,errorRetryStrategy:this._errorRetryStrategy})&&!this._isForeground&&e._retryCount<this._maxRetryCount){var _;e._retryCount++,e._retryMsg=(null==u||null==(_=u.apiError)?void 0:_.errMsg)||"unknown";let t=`任务 ${l} 在后台失败,加入重试队列 (即将第 ${e._retryCount} 次重试, 最大重试次数 ${this._maxRetryCount}, 重试原因: ${e._retryMsg})`;this.logger.warn(t),u.recovered.retry=!0,u.recovered.count=e._retryCount,u.recovered.message=e._retryMsg,e._isResolved=!1,e._isRejected=!1,this._retryQueue.push(e)}else e._isResolved=!0;a(u),null==r||r.record(u)}catch(n){let s=Object.assign({id:l,apiError:n,recovered:h});this.logger.error(`任务执行失败, 继续下一个任务,错误信息:${JSON.stringify(s)}`),e._isRejected=!0;try{null==r||r.clear()}catch(e){this.logger.error("clear error: ",JSON.stringify(Object.assign({id:l,apiError:e})))}a(s),null==r||r.record(s),await i(t)}}),i={roundTasks:t.length};t.map(e=>(t,i)=>async r=>await e(Object.assign({},t,r),i)).reduce((e,t)=>(i,r)=>e(i,t(i,r)))(i,async e=>{this.logger.info("本轮活动队列已经清空",e),this._taskStack.length>0?Promise.resolve().then(()=>{this._compose()}):(this._isRunning=!1,this._currentTask=null,this._currentBatchTasks=[])})()}clearTasks(){if(this._currentTask){if(this._currentTask._isResolved||this._currentTask._isRejected){this._currentTask=null;return}try{this._currentTask.callbackCollection&&this._currentTask.callbackCollection.
|
|
1
|
+
import{Logger as e}from"@ad-execute-manager/logger";class t{static _instance=null;_taskStack=[];_currentBatchTasks=[];_isRunning=!1;_currentTask=null;_isForeground=!0;_appShowListener=null;_appHideListener=null;_enableVisibilityListener=!1;_maxRetryCount=1;_retryQueue=[];_errorRetryStrategy={timeout:!0,background:!0};constructor(t){this.logger=new e({prefix:"AdExecuteManager",enabled:!!(null==t?void 0:t.log)}),(null==t?void 0:t.errorRetryStrategy)&&(this._errorRetryStrategy=Object.assign({},this._errorRetryStrategy,null==t?void 0:t.errorRetryStrategy)),this._enableVisibilityListener=null==t?void 0:t.enableVisibilityListener,this._maxRetryCount=(null==t?void 0:t.maxRetryCount)??1,this._enableVisibilityListener&&this._initVisibilityListener()}initialize(e){return this}static getInstance(e){return t._instance||(t._instance=new t(e)),t._instance}static build(e){return t._instance||(t._instance=new t(e)),t._instance}static new(e){return new t(e)}static getSafeInstance(){return t._instance?t._instance:(this.logger.error("AdExecuteManager实例不存在"),null)}_initVisibilityListener(){!("u"<typeof tt)&&tt.onAppShow&&tt.onAppHide?(this._appShowListener=()=>{this._isForeground=!0,this._handleAppShow()},this._appHideListener=()=>{this._isForeground=!1,this._handleAppHide()},tt.onAppShow(this._appShowListener),tt.onAppHide(this._appHideListener),this.logger.info("前后台监听器已初始化")):this.logger.warn("tt API不可用,无法监听前后台状态")}_handleAppHide(){if(this._isRunning&&this._currentBatchTasks.length>0){let e=this._currentBatchTasks.filter(e=>{var t;return e.id!==(null==(t=this._currentTask)?void 0:t.id)&&!e._isResolved&&!e._isRejected});e.length>0&&(this.logger.info(`将 ${e.length} 个未执行的任务放回任务栈,任务ID: ${e.map(e=>e.id).join(",")}`),this._taskStack=[...e,...this._taskStack],this._currentBatchTasks=this._currentBatchTasks.filter(t=>!e.some(e=>e.id===t.id)))}}_handleAppShow(){this._retryQueue.length>0&&(this.logger.info(`应用进入前台:优先执行重试队列,任务数: ${this._retryQueue.length}, 任务ID: ${this._retryQueue.map(e=>e.id).join(",")}`),this._taskStack=[...this._retryQueue,...this._taskStack],this._retryQueue=[]),this._taskStack.length>0&&!this._isRunning&&(this.logger.info(`应用进入前台:恢复待执行任务数: ${this._taskStack.length}, 任务ID: ${this._taskStack.map(e=>e.id).join(",")}`),this._compose())}destroyVisibilityListener(){this._appShowListener&&"u">typeof tt&&tt.offAppShow&&(tt.offAppShow(this._appShowListener),this._appShowListener=null),this._appHideListener&&"u">typeof tt&&tt.offAppHide&&(tt.offAppHide(this._appHideListener),this._appHideListener=null),this.logger.info("前后台监听器已销毁")}enableVisibilityListener(){this._enableVisibilityListener||(this._enableVisibilityListener=!0,this._initVisibilityListener()),this.logger.info("前后台监听器已启用")}disableVisibilityListener(){this._enableVisibilityListener&&(this._enableVisibilityListener=!1,this.destroyVisibilityListener()),this.logger.info("前后台监听器已禁用")}isVisibilityListenerEnabled(){return this._enableVisibilityListener}addTask(e,t){return e&&"function"==typeof e.ad?new Promise((i,r)=>{let s={adInstance:e,options:t.options??{},callbackCollection:t.collection??{},resolve:i,reject:r,id:`ad_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,_isResolved:!1,_isRejected:!1,_retryCount:0,_retryMsg:"ok"};this._taskStack.push(s),this._isRunning||this._compose()}):(this.logger.error("无效的广告实例 请正确实现.ad方法"),Promise.reject(Error("无效的广告实例")))}_compose(){if(0===this._taskStack.length){this._isRunning=!1,this._currentTask=null;return}if(!this._isForeground){this.logger.info(`应用处于后台,暂停任务执行,任务ID: ${this._taskStack.map(e=>e.id).join(",")}`),this._isRunning=!1;return}this._isRunning=!0;let e=[...this._taskStack];this._taskStack=[],this._currentBatchTasks=e;let t=e.map(e=>async(t,i)=>{let{adInstance:r,options:s,callbackCollection:n,resolve:a,id:l,_retryCount:o,_retryMsg:c}=e,h={count:o,retry:o>0,message:c};if(e._isResolved||e._isRejected)return void await i(t);this._currentTask=e;try{let o=async e=>{await i(Object.assign({},t,e))},c=await r.initialize(s).ad({options:s,collection:n,recovered:h},o),u=Object.assign({id:l,recovered:h},c);if(this.logger.info(`任务执行成功,成功信息:${JSON.stringify(u)}`),function({apiError:e,configuredAdTimeout:t,errorRetryStrategy:i}){var r;return!!((null==i?void 0:i.timeout)&&(null==e?void 0:e.errMsg)&&"string"==typeof e.errMsg&&e.errMsg.startsWith("ad_show_timeout: normal")&&(null==e?void 0:e.timeout)==t)||!!((null==i?void 0:i.background)&&(null==(r=e)?void 0:r.errMsg)&&"string"==typeof r.errMsg&&(r.errMsg.startsWith("app in background is not support show ad")||r.errMsg.startsWith("other controller is presented")))}({apiError:null==u?void 0:u.apiError,configuredAdTimeout:r._adTimeoutTime,errorRetryStrategy:this._errorRetryStrategy})&&!this._isForeground&&e._retryCount<this._maxRetryCount){var _;e._retryCount++,e._retryMsg=(null==u||null==(_=u.apiError)?void 0:_.errMsg)||"unknown";let t=`任务 ${l} 在后台失败,加入重试队列 (即将第 ${e._retryCount} 次重试, 最大重试次数 ${this._maxRetryCount}, 重试原因: ${e._retryMsg})`;this.logger.warn(t),u.recovered.retry=!0,u.recovered.count=e._retryCount,u.recovered.message=e._retryMsg,e._isResolved=!1,e._isRejected=!1,this._retryQueue.push(e)}else e._isResolved=!0;a(u),null==r||r.record(u)}catch(n){let s=Object.assign({id:l,apiError:n,recovered:h});this.logger.error(`任务执行失败, 继续下一个任务,错误信息:${JSON.stringify(s)}`),e._isRejected=!0;try{null==r||r.clear()}catch(e){this.logger.error("clear error: ",JSON.stringify(Object.assign({id:l,apiError:e})))}a(s),null==r||r.record(s),await i(t)}}),i={roundTasks:t.length};t.map(e=>(t,i)=>async r=>await e(Object.assign({},t,r),i)).reduce((e,t)=>(i,r)=>e(i,t(i,r)))(i,async e=>{this.logger.info("本轮活动队列已经清空",e),this._taskStack.length>0?Promise.resolve().then(()=>{this._compose()}):(this._isRunning=!1,this._currentTask=null,this._currentBatchTasks=[])})()}clearTasks(){if(this._currentTask){if(this._currentTask._isResolved||this._currentTask._isRejected){this._currentTask=null;return}try{this._currentTask.callbackCollection&&this._currentTask.callbackCollection.cancel&&this._currentTask.callbackCollection.cancel(),this._currentTask._isResolved=!0,this._currentTask.resolve()}catch(e){this.logger.error("clear current task error: ",e)}this._currentTask=null}this._currentBatchTasks.length>0&&(this._currentBatchTasks.forEach(e=>{if(e!==this._currentTask&&!e._isResolved&&!e._isRejected)try{e.callbackCollection&&e.callbackCollection.cancel&&e.callbackCollection.cancel(),e._isResolved=!0,e.resolve()}catch(e){this.logger.error("clear current batch task error: ",e)}}),this._currentBatchTasks=[]),this._taskStack.forEach(e=>{if(!e._isResolved&&!e._isRejected&&(e._isResolved=!0,e.resolve(),e.callbackCollection&&e.callbackCollection.cancel))try{e.callbackCollection.cancel()}catch(e){this.logger.error("clear task error: ",e)}}),this._retryQueue.forEach(e=>{if(!e._isResolved&&!e._isRejected&&(e._isResolved=!0,e.resolve(),e.callbackCollection&&e.callbackCollection.cancel))try{e.callbackCollection.cancel()}catch(e){this.logger.error("clear retry task error: ",e)}}),this._taskStack=[],this._retryQueue=[],this._isRunning=!1}getTaskCount(){return this._taskStack.filter(e=>!e._isResolved&&!e._isRejected).length+this._currentBatchTasks.filter(e=>e!==this._currentTask&&!e._isResolved&&!e._isRejected).length+(!this._currentTask||this._currentTask._isResolved||this._currentTask._isRejected?0:1)+this._retryQueue.filter(e=>!e._isResolved&&!e._isRejected).length}isRunning(){return this._isRunning}getCurrentTaskId(){var e;return(null==(e=this._currentTask)?void 0:e.id)||null}whenAllTasksComplete(){return new Promise(e=>{let t=null,i=()=>{let r=0===this._taskStack.length,s=!this._isRunning,n=null===this._currentTask,a=0===this._currentBatchTasks.length||this._currentBatchTasks.every(e=>e._isResolved||e._isRejected),l=0===this._retryQueue.length;r&&s&&n&&a&&l?(t&&clearTimeout(t),e()):t=setTimeout(i,500)};i()})}}let i=t;export{i as AdExecuteManager};
|
package/dist/typings/ad.d.ts
CHANGED
|
@@ -80,14 +80,10 @@ export type CallbackCollection = {
|
|
|
80
80
|
* 半途退出广告外部回调
|
|
81
81
|
*/
|
|
82
82
|
halfway?: (ctx?: IExeCallbackArgs) => void;
|
|
83
|
-
/**
|
|
84
|
-
* 完成广告外部回调 不管看不看完
|
|
85
|
-
*/
|
|
86
|
-
complete?: (ctx?: IExeCallbackArgs) => void;
|
|
87
83
|
/**
|
|
88
84
|
* 取消广告外部回调
|
|
89
85
|
*/
|
|
90
|
-
|
|
86
|
+
cancel?: (ctx?: IExeCallbackArgs) => void;
|
|
91
87
|
/**
|
|
92
88
|
* 展示广告外部回调
|
|
93
89
|
*/
|
|
@@ -115,6 +111,20 @@ export type RecoveredInfo = {
|
|
|
115
111
|
*/
|
|
116
112
|
message: string;
|
|
117
113
|
};
|
|
114
|
+
export type IApiError = {
|
|
115
|
+
/**
|
|
116
|
+
* 错误信息
|
|
117
|
+
*/
|
|
118
|
+
errMsg?: string;
|
|
119
|
+
/**
|
|
120
|
+
* 错误码
|
|
121
|
+
*/
|
|
122
|
+
errorCode?: number;
|
|
123
|
+
/**
|
|
124
|
+
* 错误信息
|
|
125
|
+
*/
|
|
126
|
+
message?: string;
|
|
127
|
+
};
|
|
118
128
|
export type ICallbackArgs = {
|
|
119
129
|
/**
|
|
120
130
|
* 广告执行场景
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ad-execute-manager/core",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.4",
|
|
4
4
|
"description": "Core functionality for ad execution management including AdExecuteManager, utility functions, and middleware composition.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
},
|
|
53
53
|
|
|
54
54
|
"peerDependencies": {
|
|
55
|
-
"@ad-execute-manager/logger": "^2.0.
|
|
55
|
+
"@ad-execute-manager/logger": "^2.0.4"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@babel/eslint-parser": "^7.28.5",
|