UNPKG

js-use-core

Version:

JavaScript Comprehensive tool library, including full screen, copy and paste functions

2 lines (1 loc) 29.1 kB
class EventEmitter{constructor(){this.events=new Map,this.maxListeners=10}on(e,t,i){if("function"!=typeof t)throw new Error("Listener must be a function");const r={listener:t,once:i?.once||!1,priority:i?.priority||0};this.events.has(e)||this.events.set(e,[]);const n=this.events.get(e);n.length,this.maxListeners;let s=!1;for(let e=0;e<n.length;e++)if(r.priority>(n[e].priority||0)){n.splice(e,0,r),s=!0;break}return s||n.push(r),this}once(e,t,i){return this.on(e,t,{once:!0,priority:i})}off(e,t){if(!this.events.has(e))return this;const i=this.events.get(e);if(t){const r=i.findIndex(e=>e.listener===t);-1!==r&&(i.splice(r,1),0===i.length&&this.events.delete(e))}else this.events.delete(e);return this}emit(e,...t){if(!this.events.has(e))return!1;const i=this.events.get(e).slice(),r=[];for(const e of i)try{e.listener.apply(this,t),e.once&&r.push(e)}catch(e){}if(r.length>0){const t=this.events.get(e);if(t){for(const e of r){const i=t.indexOf(e);-1!==i&&t.splice(i,1)}0===t.length&&this.events.delete(e)}}return!0}listenerCount(e){return this.events.get(e)?.length||0}listeners(e){return this.events.get(e)?.map(e=>e.listener)||[]}eventNames(){return Array.from(this.events.keys())}removeAllListeners(e){return e?this.events.delete(e):this.events.clear(),this}setMaxListeners(e){if(e<0||!Number.isInteger(e))throw new Error("Max listeners must be a non-negative integer");return this.maxListeners=e,this}getMaxListeners(){return this.maxListeners}prependListener(e,t){return this.on(e,t,{priority:Number.MAX_SAFE_INTEGER})}prependOnceListener(e,t){return this.once(e,t,Number.MAX_SAFE_INTEGER)}}var e,t,i,r,n,s,a,o,h,c,l;!function(e){e.USER_ERROR="USER_ERROR",e.SYSTEM_ERROR="SYSTEM_ERROR",e.NETWORK_ERROR="NETWORK_ERROR",e.PERMISSION_ERROR="PERMISSION_ERROR",e.CONFIG_ERROR="CONFIG_ERROR",e.VALIDATION_ERROR="VALIDATION_ERROR",e.TIMEOUT_ERROR="TIMEOUT_ERROR",e.UNSUPPORTED_ERROR="UNSUPPORTED_ERROR",e.INTERNAL_ERROR="INTERNAL_ERROR",e.EXTERNAL_ERROR="EXTERNAL_ERROR",e.UNKNOWN_ERROR="UNKNOWN_ERROR"}(e||(e={})),function(e){e.LOW="low",e.MEDIUM="medium",e.HIGH="high",e.CRITICAL="critical"}(t||(t={})),function(e){e.USER_ERROR="USER_ERROR",e.SYSTEM_ERROR="SYSTEM_ERROR",e.NETWORK_ERROR="NETWORK_ERROR",e.PERMISSION_ERROR="PERMISSION_ERROR",e.CONFIG_ERROR="CONFIG_ERROR",e.TIMEOUT_ERROR="TIMEOUT_ERROR",e.VALIDATION_ERROR="VALIDATION_ERROR",e.INTERNAL_ERROR="INTERNAL_ERROR",e.UNKNOWN_ERROR="UNKNOWN_ERROR"}(i||(i={})),function(e){e[e.DEBUG=0]="DEBUG",e[e.INFO=1]="INFO",e[e.WARN=2]="WARN",e[e.ERROR=3]="ERROR"}(r||(r={}));class Logger{constructor(e="Core",t){this.level=r.INFO,this.logs=[],this.maxLogs=1e3,this.enableConsole=!0,this.module=e,t&&(this.level=t.level??r.INFO,this.maxLogs=t.maxLogs??1e3,this.enableConsole=t.enableConsole??!0)}setLevel(e){this.level=e}getLevel(){return this.level}debug(e,t){this.log(r.DEBUG,e,t)}info(e,t){this.log(r.INFO,e,t)}warn(e,t){this.log(r.WARN,e,t)}error(e,t){this.log(r.ERROR,e,t)}log(e,t,i){if(e<this.level)return;const r={level:e,message:t,timestamp:Date.now(),module:this.module,data:i};this.logs.push(r),this.logs.length>this.maxLogs&&this.logs.shift(),this.enableConsole&&this.outputToConsole(r)}outputToConsole(e){new Date(e.timestamp).toISOString(),r[e.level],e.module,e.message,void 0!==e.data&&e.data;switch(e.level){case r.DEBUG:case r.INFO:case r.WARN:case r.ERROR:}}getLogs(){return[...this.logs]}getLogsByLevel(e){return this.logs.filter(t=>t.level===e)}getLogsByTimeRange(e,t){return this.logs.filter(i=>i.timestamp>=e&&i.timestamp<=t)}clear(){this.logs=[]}setMaxLogs(e){if(e<0)throw new Error("Max logs must be non-negative");this.maxLogs=e,this.logs.length>e&&(this.logs=this.logs.slice(-e))}setConsoleOutput(e){this.enableConsole=e}exportLogs(){return JSON.stringify(this.logs,null,2)}importLogs(e){try{const t=JSON.parse(e);Array.isArray(t)&&(this.logs=t.filter(e=>e&&"number"==typeof e.level&&"string"==typeof e.message&&"number"==typeof e.timestamp))}catch(e){this.error("Failed to import logs",e)}}createChild(e){return new Logger(`${this.module}.${e}`,{level:this.level,maxLogs:this.maxLogs,enableConsole:this.enableConsole})}}class u extends Error{constructor(e,t,i){super(t),this.name="CustomError",this.type=e,this.code=i?.code,this.context=i?.context,this.recoverable=i?.recoverable??!1,i?.cause&&(this.cause=i.cause),Error.captureStackTrace&&Error.captureStackTrace(this,u)}}class ErrorHandler{constructor(e){this.errorSolutions=new Map,this.logger=e||new Logger("ErrorHandler"),this.initializeErrorSolutions()}handleError(e,t){const i=this.classifyError(e),r={module:"Unknown",method:"Unknown",timestamp:Date.now(),userAgent:"undefined"!=typeof navigator?navigator.userAgent:"Node.js",...t},n={type:i,severity:this.getErrorSeverity(i),message:e.message,userMessage:this.getUserFriendlyMessage(e,i),originalError:e,context:r,code:this.getErrorCode(e)||this.generateErrorCode(i),recoverable:this.isRecoverableError(e),solutions:this.getErrorSolutions(e),id:this.generateErrorId(),processedAt:Date.now(),relatedErrors:[]};return this.logger.error(`[${i}] ${n.message}`,{error:e.message,stack:e.stack,context:r,recoverable:n.recoverable}),n}createError(e,t,i){const r={module:"Unknown",method:"Unknown",timestamp:Date.now(),userAgent:"undefined"!=typeof navigator?navigator.userAgent:"Node.js",...i?.context};return new u(e,t,{code:i?.code,context:r,recoverable:i?.recoverable,cause:i?.cause})}isRecoverableError(t){if(t instanceof u)return t.recoverable;switch(this.classifyError(t)){case e.NETWORK_ERROR:case e.TIMEOUT_ERROR:return!0;case e.PERMISSION_ERROR:case e.SYSTEM_ERROR:return!1;case e.USER_ERROR:case e.CONFIG_ERROR:return!0;default:return!1}}getErrorSolution(e){const t=this.getErrorCode(e);if(t&&this.errorSolutions.has(t))return this.errorSolutions.get(t);const i=this.classifyError(e);return this.getDefaultSolution(i)}getErrorSolutions(e){const t=this.getErrorSolution(e);return t?[{description:t,steps:[t],automatic:!1,priority:1}]:[]}getErrorSeverity(i){switch(i){case e.USER_ERROR:case e.CONFIG_ERROR:return t.LOW;case e.NETWORK_ERROR:case e.TIMEOUT_ERROR:return t.MEDIUM;case e.PERMISSION_ERROR:case e.VALIDATION_ERROR:return t.HIGH;case e.SYSTEM_ERROR:case e.INTERNAL_ERROR:return t.CRITICAL;default:return t.MEDIUM}}generateErrorCode(e){return`${e}_${Date.now().toString(36)}_${Math.random().toString(36).substr(2,5)}`.toUpperCase()}generateErrorId(){return`error_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}addErrorSolution(e,t){this.errorSolutions.set(e,t)}addErrorSolutions(e){for(const[t,i]of Object.entries(e))this.errorSolutions.set(t,i)}classifyError(t){if(t instanceof u)return t.type;const i=(t.message||"").toLowerCase(),r=(t.name||"").toLowerCase();return i.includes("network")||i.includes("fetch")||i.includes("xhr")||r.includes("networkerror")?e.NETWORK_ERROR:i.includes("timeout")||i.includes("timed out")||r.includes("timeouterror")?e.TIMEOUT_ERROR:i.includes("permission")||i.includes("denied")||i.includes("unauthorized")||i.includes("forbidden")||r.includes("notallowederror")?e.PERMISSION_ERROR:i.includes("not supported")||i.includes("not available")||i.includes("not implemented")||r.includes("notsupportederror")?e.SYSTEM_ERROR:i.includes("invalid")||i.includes("configuration")||i.includes("config")||r.includes("configerror")?e.CONFIG_ERROR:t instanceof TypeError||t instanceof RangeError||i.includes("invalid argument")||i.includes("invalid parameter")?e.USER_ERROR:e.UNKNOWN_ERROR}getUserFriendlyMessage(t,i){switch(i){case e.NETWORK_ERROR:return"网络连接失败,请检查网络连接后重试";case e.TIMEOUT_ERROR:return"操作超时,请稍后重试";case e.PERMISSION_ERROR:return"权限不足,请检查浏览器权限设置";case e.SYSTEM_ERROR:return"当前浏览器不支持此功能,请使用其他浏览器或升级浏览器版本";case e.CONFIG_ERROR:return"配置参数错误,请检查配置";case e.USER_ERROR:return"输入参数错误,请检查输入参数";default:return t.message||"发生未知错误"}}getErrorCode(e){if(e instanceof u)return e.code;const t=e;return t.code||t.errno||void 0}getDefaultSolution(t){switch(t){case e.NETWORK_ERROR:return"请检查网络连接,确保网络正常后重试";case e.TIMEOUT_ERROR:return"请稍后重试,或增加超时时间设置";case e.PERMISSION_ERROR:return"请在浏览器设置中允许相关权限,或使用HTTPS协议";case e.SYSTEM_ERROR:return"请使用支持此功能的现代浏览器,或升级浏览器版本";case e.CONFIG_ERROR:return"请检查配置参数是否正确,参考文档进行配置";case e.USER_ERROR:return"请检查输入参数的类型和格式是否正确";default:return null}}initializeErrorSolutions(){this.errorSolutions.set("ENOTFOUND","域名解析失败,请检查网络连接"),this.errorSolutions.set("ECONNREFUSED","连接被拒绝,请检查服务器状态"),this.errorSolutions.set("ETIMEDOUT","连接超时,请检查网络连接或稍后重试"),this.errorSolutions.set("CERT_UNTRUSTED","SSL证书不受信任,请检查证书配置"),this.errorSolutions.set("MIXED_CONTENT","混合内容错误,请使用HTTPS协议")}}class Cache{constructor(e){this.cache=new Map,this.config={maxSize:e?.maxSize??100,defaultTTL:e?.defaultTTL??3e5,enableLRU:e?.enableLRU??!0,cleanupInterval:e?.cleanupInterval??6e4},this.startCleanup()}set(e,t,i){const r=Date.now(),n={value:t,expireAt:r+(i??this.config.defaultTTL),createdAt:r,accessCount:0,lastAccessed:r};this.cache.size>=this.config.maxSize&&!this.cache.has(e)&&this.evictLRU(),this.cache.set(e,n)}get(e){const t=this.cache.get(e);if(!t)return;const i=Date.now();if(!(i>t.expireAt))return t.accessCount++,t.lastAccessed=i,t.value;this.cache.delete(e)}has(e){const t=this.cache.get(e);return!!t&&(!(Date.now()>t.expireAt)||(this.cache.delete(e),!1))}delete(e){return this.cache.delete(e)}clear(){this.cache.clear()}size(){return this.cache.size}keys(){return Array.from(this.cache.keys())}getInfo(e){const t=this.cache.get(e);if(t){if(!(Date.now()>t.expireAt))return{...t};this.cache.delete(e)}}touch(e,t){const i=this.cache.get(e);if(!i)return!1;const r=Date.now();if(r>i.expireAt)return this.cache.delete(e),!1;const n=t??this.config.defaultTTL;return i.expireAt=r+n,i.lastAccessed=r,!0}async getOrSet(e,t,i){const r=this.get(e);if(void 0!==r)return r;const n=await t();return this.set(e,n,i),n}mset(e,t){for(const[i,r]of e)this.set(i,r,t)}mget(e){return e.map(e=>this.get(e))}mdel(e){let t=0;for(const i of e)this.delete(i)&&t++;return t}getStats(){let e=0,t=0;const i=Date.now();for(const[r,n]of this.cache.entries())e+=n.accessCount,i>n.expireAt&&t++;return{size:this.cache.size,maxSize:this.config.maxSize,hitRate:e>0?(e-t)/e:0,totalAccess:e,expiredCount:t}}cleanup(){const e=Date.now();let t=0;for(const[i,r]of this.cache.entries())e>r.expireAt&&(this.cache.delete(i),t++);return t}evictLRU(){if(!this.config.enableLRU||0===this.cache.size)return;let e=null,t=1/0;for(const[i,r]of this.cache.entries())r.lastAccessed<t&&(t=r.lastAccessed,e=i);e&&this.cache.delete(e)}startCleanup(){this.cleanupTimer&&clearInterval(this.cleanupTimer),this.cleanupTimer=setInterval(()=>{this.cleanup()},this.config.cleanupInterval)}stopCleanup(){this.cleanupTimer&&(clearInterval(this.cleanupTimer),this.cleanupTimer=void 0)}updateConfig(e){if(this.config={...this.config,...e},void 0!==e.cleanupInterval&&this.startCleanup(),void 0!==e.maxSize&&this.cache.size>e.maxSize)for(;this.cache.size>e.maxSize;)this.evictLRU()}destroy(){this.stopCleanup(),this.clear()}}class BaseManager{constructor(e,t="BaseManager"){this.initialized=!1,this.destroyed=!1,this.initializing=!1,this.options=this.mergeDefaultOptions(e),this.logger=new Logger(t,{level:this.options.debug?0:1,enableConsole:this.options.debug}),this.eventEmitter=new EventEmitter,this.errorHandler=new ErrorHandler(this.logger),this.options.cache&&(this.cache=new Cache),this.setupErrorHandling(),this.startAutoInitialization()}on(e,t,i){return this.eventEmitter.on(e,t,i),this}off(e,t){return this.eventEmitter.off(e,t),this}emit(e,...t){return this.eventEmitter.emit(e,...t)}once(e,t,i){return this.eventEmitter.once(e,t,i),this}listenerCount(e){return this.eventEmitter.listenerCount(e)}eventNames(){return this.eventEmitter.eventNames()}handleError(e,t){const i={module:this.constructor.name,method:t},r=this.errorHandler.handleError(e,i);return this.emit("error",r),r}validateInput(e,t){try{if(t.type){const i=typeof e;if(i!==t.type)throw this.errorHandler.createError("USER_ERROR",`Expected ${t.type}, got ${i}`,{context:{method:"validateInput"}})}if(t.required&&null==e)throw this.errorHandler.createError("USER_ERROR","Required parameter is missing",{context:{method:"validateInput"}});if(t.isArray&&!Array.isArray(e))throw this.errorHandler.createError("USER_ERROR","Expected array",{context:{method:"validateInput"}});if(t.properties&&"object"==typeof e&&null!==e)for(const[i,r]of Object.entries(t.properties))if(!this.validateInput(e[i],r))return!1;return!0}catch(e){return this.handleError(e,"validateInput"),!1}}async safeExecute(e,t,i){const r=i??this.options.retries??0;let n=null;for(let i=0;i<=r;i++)try{const r=new Promise((e,i)=>{setTimeout(()=>{i(this.errorHandler.createError("TIMEOUT_ERROR",`Operation timed out after ${this.options.timeout}ms`,{context:{method:t}}))},this.options.timeout)}),n=await Promise.race([e(),r]);return i>0&&this.logger.info(`Operation succeeded after ${i} retries`,{context:t}),n}catch(e){if(n=e,i===r||!this.errorHandler.isRecoverableError(n))throw this.handleError(n,t);const s=Math.min(1e3*Math.pow(2,i),5e3);this.logger.warn(`Operation failed, retrying in ${s}ms (attempt ${i+1}/${r+1})`,{context:t,error:n.message}),await new Promise(e=>setTimeout(e,s))}throw this.handleError(n,t)}getCached(e){return this.cache?.get(e)}setCached(e,t,i){this.cache?.set(e,t,i)}async getOrSetCached(e,t,i){return this.cache?this.cache.getOrSet(e,t,i):t()}async ensureInitialized(){if(this.destroyed)throw this.errorHandler.createError("SYSTEM_ERROR","Manager has been destroyed and cannot be used.",{context:{method:"ensureInitialized"}});if(!this.initialized)if(this.initPromise)try{await this.initPromise,this.initPromise=void 0}catch(e){throw this.errorHandler.createError("SYSTEM_ERROR",`Manager initialization failed: ${e.message}`,{context:{method:"ensureInitialized"}})}else if(!this.initializing){this.initializing=!0;try{await this.initialize()}finally{this.initializing=!1}}}ensureInitializedSync(){if(!this.initialized)throw this.errorHandler.createError("SYSTEM_ERROR","Manager not initialized. Operations requiring initialization should be awaited.",{context:{method:"ensureInitializedSync"}})}ensureNotDestroyed(){if(this.destroyed)throw this.errorHandler.createError("SYSTEM_ERROR","Manager has been destroyed and cannot be used.",{context:{method:"ensureNotDestroyed"}})}async ready(){await this.ensureInitialized()}getStatus(){return{initialized:this.initialized,destroyed:this.destroyed,eventListeners:this.eventNames().reduce((e,t)=>e+this.listenerCount(t),0),cacheSize:this.cache?.size(),initializing:this.initializing||!!this.initPromise}}updateOptions(e){this.options={...this.options,...e},void 0!==e.debug&&(this.logger.setLevel(e.debug?0:1),this.logger.setConsoleOutput(e.debug)),this.emit("optionsUpdated",this.options)}mergeDefaultOptions(e){return{...this.getDefaultOptions(),...e}}setupErrorHandling(){"undefined"!=typeof window?window.addEventListener("unhandledrejection",e=>{this.handleError(new Error(e.reason),"unhandledrejection")}):"undefined"!=typeof process&&process.on("unhandledRejection",e=>{this.handleError(new Error(String(e)),"unhandledRejection")})}startAutoInitialization(){this.initPromise=this.initialize().catch(e=>(this.logger.error("Auto-initialization failed:",e),Promise.reject(e))),this.initPromise.catch(()=>{})}baseDestroy(){this.destroyed||(this.emit("beforeDestroy"),this.eventEmitter.removeAllListeners(),this.cache?.destroy(),this.logger.clear(),this.destroyed=!0,this.initialized=!1,this.emit("destroyed"))}}function d(e){return e instanceof File}function g(e){if(!e)return"";const t=e.split(".");return t.length>1&&t.pop()?.toLowerCase()||""}function R(e){return{"image/jpeg":"jpg","image/jpg":"jpg","image/png":"png","image/gif":"gif","image/webp":"webp","audio/mpeg":"mp3","audio/mp3":"mp3","audio/wav":"wav","audio/ogg":"ogg","video/mp4":"mp4","video/webm":"webm","video/ogg":"ogv","application/pdf":"pdf","text/plain":"txt","text/html":"html","text/css":"css","text/javascript":"js","application/json":"json"}[e]||""}function m(e){return{jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp",mp3:"audio/mpeg",wav:"audio/wav",ogg:"audio/ogg",mp4:"video/mp4",webm:"video/webm",ogv:"video/ogg",pdf:"application/pdf",txt:"text/plain",html:"text/html",css:"text/css",js:"text/javascript",json:"application/json"}[e.toLowerCase()]||"application/octet-stream"}function E(e=""){return`file_${(new Date).getTime()}_${Math.floor(1e4*Math.random())}${e?"."+e:""}`}!function(e){e.IMAGE="image",e.AUDIO="audio",e.VIDEO="video",e.DOCUMENT="document",e.ARCHIVE="archive",e.CODE="code",e.OTHER="other"}(n||(n={})),function(e){e.DESKTOP="desktop",e.MOBILE="mobile",e.TABLET="tablet",e.TV="tv",e.WEARABLE="wearable",e.UNKNOWN="unknown"}(s||(s={})),function(e){e.WINDOWS="windows",e.MACOS="macos",e.LINUX="linux",e.ANDROID="android",e.IOS="ios",e.UNKNOWN="unknown"}(a||(a={})),function(e){e.CHROME="chrome",e.FIREFOX="firefox",e.SAFARI="safari",e.EDGE="edge",e.IE="ie",e.OPERA="opera",e.UNKNOWN="unknown"}(o||(o={})),function(e){e.NORMAL="normal",e.ITALIC="italic",e.OBLIQUE="oblique"}(h||(h={})),function(e){e[e.THIN=100]="THIN",e[e.EXTRA_LIGHT=200]="EXTRA_LIGHT",e[e.LIGHT=300]="LIGHT",e[e.NORMAL=400]="NORMAL",e[e.MEDIUM=500]="MEDIUM",e[e.SEMI_BOLD=600]="SEMI_BOLD",e[e.BOLD=700]="BOLD",e[e.EXTRA_BOLD=800]="EXTRA_BOLD",e[e.BLACK=900]="BLACK"}(c||(c={})),function(e){e.TEXT="text/plain",e.HTML="text/html",e.RTF="text/rtf",e.IMAGE="image/png",e.JSON="application/json"}(l||(l={}));class p extends BaseManager{getDefaultOptions(){return{debug:!1,timeout:6e4,retries:1,cache:!0,cacheTTL:3e5,maxImageSize:4096,defaultQuality:.8,defaultFormat:"jpeg",enableSizeValidation:!0,supportedFormats:["jpeg","png","webp","gif","bmp"],canvasContextOptions:{alpha:!0,desynchronized:!1,colorSpace:"srgb"}}}async initialize(){if(!this.initialized)try{this.checkBrowserSupport(),this.initializeCanvas(),this.initialized=!0,this.emit("initialized"),this.logger.info("ImageManager initialized successfully")}catch(e){throw this.handleError(e,"initialize")}}destroy(){this.canvas&&(this.canvas.width=0,this.canvas.height=0,this.canvas=void 0,this.context=void 0),this.baseDestroy(),this.logger.info("ImageManager destroyed")}async blobToDataURL(e){if(await this.ensureInitialized(),this.ensureNotDestroyed(),!e||"number"!=typeof e.size)throw this.handleError(new Error("Invalid Blob object"),"blobToDataURL");const t=Date.now();try{return{result:await this.safeExecute(()=>new Promise((t,i)=>{const r=new FileReader;r.onload=()=>{"string"==typeof r.result?t(r.result):i(new Error("FileReader result is not a string"))},r.onerror=()=>i(new Error("Failed to convert Blob to DataURL")),r.readAsDataURL(e)}),"blobToDataURL"),duration:Date.now()-t,fromCache:!1}}catch(e){throw this.handleError(e,"blobToDataURL")}}imageToDataURL(e,t=this.options.defaultFormat,i=this.options.defaultQuality){if(this.ensureInitializedSync(),this.ensureNotDestroyed(),!e||!e.naturalWidth||!e.naturalHeight)throw this.handleError(new Error("Invalid or unloaded image element"),"imageToDataURL");const r=Date.now();try{if(!this.options.supportedFormats.includes(t))throw new Error(`Unsupported image format: ${t}`);const n=document.createElement("canvas");n.width=e.naturalWidth||e.width,n.height=e.naturalHeight||e.height;const s=n.getContext("2d",this.options.canvasContextOptions);if(!s)throw new Error("Failed to create canvas 2d context");s.drawImage(e,0,0);const a=`image/${t}`;return{result:n.toDataURL(a,i),originalInfo:this.extractImageInfo(e),duration:Date.now()-r,fromCache:!1}}catch(e){throw this.handleError(e,"imageToDataURL")}}async dataURLToImage(e){if(await this.ensureInitialized(),this.ensureNotDestroyed(),!this.validateInput(e,{type:"string",required:!0}))throw this.handleError(new Error("Invalid DataURL parameter"),"dataURLToImage");if(!e.startsWith("data:image/"))throw this.handleError(new Error("DataURL is not an image format"),"dataURLToImage");const t=Date.now(),i=`dataurl_to_image_${this.hashString(e)}`;try{const r=this.getCached(i);if(r)return{result:r,duration:Date.now()-t,fromCache:!0};const n=await this.safeExecute(()=>new Promise((t,i)=>{const r=new Image;r.onload=()=>{if(this.options.enableSizeValidation){const e=this.options.maxImageSize;if(r.naturalWidth>e||r.naturalHeight>e)return void i(new Error(`Image size ${r.naturalWidth}x${r.naturalHeight} exceeds maximum ${e}x${e}`))}t(r)},r.onerror=()=>i(new Error("Failed to load image from DataURL")),r.src=e}),"dataURLToImage");return this.setCached(i,n,3e5),{result:n,processedInfo:this.extractImageInfo(n),duration:Date.now()-t,fromCache:!1}}catch(e){throw this.handleError(e,"dataURLToImage")}}dataURLtoBlob(e){if(this.ensureInitializedSync(),this.ensureNotDestroyed(),!this.validateInput(e,{type:"string",required:!0}))throw this.handleError(new Error("Invalid DataURL parameter"),"dataURLtoBlob");const t=Date.now();try{const i=e.split(",");if(2!==i.length)throw new Error("Invalid DataURL format");const r=i[0].match(/:(.*?);/)?.[1]||"image/jpeg",n=atob(i[1]);let s=n.length;const a=new Uint8Array(s);for(;s--;)a[s]=n.charCodeAt(s);return{result:new Blob([a],{type:r}),duration:Date.now()-t,fromCache:!1}}catch(e){throw this.handleError(e,"dataURLtoBlob")}}dataURLtoImgBlob(e){const t=this.dataURLtoBlob(e);if(!t.result.type.startsWith("image/"))throw this.handleError(new Error("DataURL is not an image format"),"dataURLtoImgBlob");return t}dataURLtoFile(e,t){this.ensureInitializedSync(),this.ensureNotDestroyed();const i=this.dataURLtoBlob(e),r=i.result,n=Date.now();try{let e,s=r.type||"application/octet-stream",a=R(s);e=t?!t.includes(".")&&a?`${t}.${a}`:t:E(a);return{result:new File([r],e,{type:s}),duration:i.duration+(Date.now()-n),fromCache:!1}}catch(e){throw this.handleError(e,"dataURLtoFile")}}async imgConvert(e,t){if(await this.ensureInitialized(),this.ensureNotDestroyed(),!d(e))throw this.handleError(new Error("Parameter must be a File object"),"imgConvert");if(!e.type.startsWith("image/"))throw this.handleError(new Error("File is not an image format"),"imgConvert");const{format:i,quality:r=this.options.defaultQuality}=t;if(!this.options.supportedFormats.includes(i))throw this.handleError(new Error(`Unsupported image format: ${i}`),"imgConvert");const n=Date.now(),s=`img_convert_${e.name}_${e.size}_${i}_${r}`;try{const t=this.getCached(s);if(t)return{result:t,duration:Date.now()-n,fromCache:!0};const a=await this.safeExecute(async()=>{const t=m(i),n=await this.createImageFromFile(e),s=this.extractImageInfo(n,e),a=document.createElement("canvas");a.width=n.naturalWidth,a.height=n.naturalHeight;const o=a.getContext("2d",this.options.canvasContextOptions);if(!o)throw new Error("Failed to create canvas 2d context");"jpeg"!==i||"image/png"!==e.type&&"image/gif"!==e.type||(o.fillStyle="#FFFFFF",o.fillRect(0,0,a.width,a.height)),o.drawImage(n,0,0);const h=a.toDataURL(t,r);let c=e.name;const l=c.lastIndexOf(".");-1!==l&&(c=c.substring(0,l)),c=`${c}.${i}`;const u=this.dataURLtoFile(h,c).result;return{file:u,originalInfo:s,processedInfo:this.extractImageInfo(n,u)}},"imgConvert");return this.setCached(s,a.file,6e5),{result:a.file,originalInfo:a.originalInfo,processedInfo:a.processedInfo,duration:Date.now()-n,fromCache:!1}}catch(e){throw this.handleError(e,"imgConvert")}}async imgCompress(e,t={}){if(await this.ensureInitialized(),this.ensureNotDestroyed(),!d(e))throw this.handleError(new Error("Parameter must be a File object"),"imgCompress");if(!e.type.startsWith("image/"))throw this.handleError(new Error("File is not an image format"),"imgCompress");const{quality:i=this.options.defaultQuality,maxWidth:r,maxHeight:n,format:s,maintainAspectRatio:a=!0,backgroundColor:o="#FFFFFF"}=t,h=Date.now(),c=`img_compress_${e.name}_${e.size}_${i}_${r}_${n}_${s}`;try{const t=this.getCached(c);if(t)return{result:t,duration:Date.now()-h,fromCache:!0,compressionRatio:t.size/e.size};const l=await this.safeExecute(async()=>{let t=e.type;s&&(t=m(s)||e.type);const h=await this.createImageFromFile(e),c=this.extractImageInfo(h,e);let l=h.naturalWidth,u=h.naturalHeight;r&&l>r&&(a&&(u=u*r/l),l=r),n&&u>n&&(a&&(l=l*n/u),u=n);const d=document.createElement("canvas");d.width=Math.round(l),d.height=Math.round(u);const g=d.getContext("2d",this.options.canvasContextOptions);if(!g)throw new Error("Failed to create canvas 2d context");g.imageSmoothingEnabled=!0,g.imageSmoothingQuality="high","image/jpeg"===t&&(g.fillStyle=o,g.fillRect(0,0,d.width,d.height)),g.drawImage(h,0,0,d.width,d.height);const R=d.toDataURL(t,i);let E=e.name;if(s){const e=E.lastIndexOf(".");-1!==e&&(E=E.substring(0,e)),E=`${E}.${s}`}const p=this.dataURLtoFile(R,E).result;return{file:p,originalInfo:c,processedInfo:this.extractImageInfo(h,p)}},"imgCompress");this.setCached(c,l.file,6e5);const u=l.file.size/e.size;return{result:l.file,originalInfo:l.originalInfo,processedInfo:l.processedInfo,duration:Date.now()-h,fromCache:!1,compressionRatio:u}}catch(e){throw this.handleError(e,"imgCompress")}}async getImageDimensions(e){if(await this.ensureInitialized(),this.ensureNotDestroyed(),!d(e)||!e.type.startsWith("image/"))throw this.handleError(new Error("Parameter must be an image file"),"getImageDimensions");try{const t=await this.createImageFromFile(e);return{width:t.naturalWidth,height:t.naturalHeight,aspectRatio:t.naturalWidth/t.naturalHeight}}catch(e){throw this.handleError(e,"getImageDimensions")}}checkBrowserSupport(){const e=[{name:"Canvas",api:"undefined"!=typeof HTMLCanvasElement},{name:"CanvasRenderingContext2D",api:"undefined"!=typeof CanvasRenderingContext2D},{name:"Image",api:"undefined"!=typeof Image},{name:"FileReader",api:"undefined"!=typeof FileReader}].filter(e=>!e.api);if(e.length>0)throw new Error(`Unsupported browser APIs: ${e.map(e=>e.name).join(", ")}`)}initializeCanvas(){if("undefined"!=typeof document&&(this.canvas=document.createElement("canvas"),this.context=this.canvas.getContext("2d",this.options.canvasContextOptions)||void 0,!this.context))throw new Error("Failed to create canvas 2d context")}async createImageFromFile(e){const t=await this.blobToDataURL(e);return(await this.dataURLToImage(t.result)).result}extractImageInfo(e,t){const i=t?function(e){let t="",i="";"string"==typeof e?(i=g(e),t=m(i)):(t=e.type||"",i=e.name?g(e.name):R(t));const r=t.startsWith("image/"),s=t.startsWith("audio/"),a=t.startsWith("video/"),o=t.startsWith("application/")||t.startsWith("text/");let h;return h=r?n.IMAGE:s?n.AUDIO:a?n.VIDEO:o?n.DOCUMENT:t.includes("zip")||t.includes("rar")||t.includes("tar")?n.ARCHIVE:t.includes("javascript")||t.includes("json")||"js"===i||"ts"===i?n.CODE:n.OTHER,{isImage:r,isAudio:s,isVideo:a,isDocument:o,type:h,mimeType:t,extension:i,isSupported:!0}}(t):{type:"image",extension:"jpg"};return{name:t?.name||"image",size:t?.size||0,type:i.type,mimeType:t?.type||"image/jpeg",extension:i.extension,lastModified:t?.lastModified||Date.now(),dimensions:{width:e.naturalWidth,height:e.naturalHeight,aspectRatio:e.naturalWidth/e.naturalHeight}}}hashString(e){let t=0;for(let i=0;i<e.length;i++){t=(t<<5)-t+e.charCodeAt(i),t&=t}return Math.abs(t).toString(36)}}const f=new p;async function w(e){f.getStatus().initialized||await f.initialize();return(await f.blobToDataURL(e)).result}function O(e,t="jpeg",i=.9){if(!e||!e.naturalWidth||!e.naturalHeight)throw new Error("Invalid or unloaded image element");const r=document.createElement("canvas");r.width=e.naturalWidth||e.width,r.height=e.naturalHeight||e.height;const n=r.getContext("2d");if(!n)throw new Error("无法创建canvas 2d上下文");return n.drawImage(e,0,0),r.toDataURL(`image/${t}`,i)}async function I(e){f.getStatus().initialized||await f.initialize();return(await f.dataURLToImage(e)).result}function v(e){const t=e.split(",");if(2!==t.length)throw new Error("Invalid DataURL format");const i=t[0].match(/:(.*?);/)?.[1]||"image/jpeg",r=atob(t[1]);let n=r.length;const s=new Uint8Array(n);for(;n--;)s[n]=r.charCodeAt(n);return new Blob([s],{type:i})}function y(e){const t=v(e);if(!t.type.startsWith("image/"))throw new Error("提供的DataURL不是图片格式");return t}function S(e,t){const i=v(e);let r,n=i.type||"application/octet-stream",s=R(n);return r=t?!t.includes(".")&&s?`${t}.${s}`:t:E(s),new File([i],r,{type:n})}async function T(e,t){f.getStatus().initialized||await f.initialize();return(await f.imgConvert(e,t)).result}async function L(e,t={}){f.getStatus().initialized||await f.initialize();return(await f.imgCompress(e,t)).result}export{p as ImageManager,w as blobToDataURL,I as dataURLToImage,v as dataURLtoBlob,S as dataURLtoFile,y as dataURLtoImgBlob,O as imageToDataURL,L as imgCompress,T as imgConvert};