!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(exports):"function"==typeof define&&define.amd?define(["exports"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).Mc={})}(this,(function(e){"use strict";class s{constructor(e){this.opt={sync:!1,heartbeatInterval:5e3,...e},this.selfPost=void 0,this.selfModuleId=void 0,this.modules=new Map,this.heartbeatInterval=this.opt.heartbeatInterval,this.msgHistory=new Map,this.heartbeatTimers=new Map,this.messageHandlers=new Map,window.addEventListener("unload",(()=>{this.modules.forEach((e=>{e.port&&"Listen"===e.status&&e.port.close()}))})),this.opt.sync||window.addEventListener("load",(()=>{this.init()}))}init(){const e=document.querySelectorAll("iframe");e.length&&this.loadModule(e),this.registerDefaultHandlers(),window.addEventListener("message",this.receiveMessage.bind(this))}receiveMessageScheduler(e){const{data:s,port:t}=e,o=s.moduleId,i=this.modules.get(o);switch(console.log("receiveMessageScheduler",s.type,e),s.type){case"INIT_MODULE":this.selfPost=t,this.selfModuleId=s.moduleId,this.selfPost.onmessage=this.receiveMessageScheduler.bind(this),this.selfPost.onmessageerror=e=>{console.error("receiveMessageScheduler",e)},this.selfPost?.postMessage({type:"INIT_MODULE_ACK",moduleId:s.moduleId});break;case"INIT_MODULE_ACK":if(!i)return;i.status="Listen",this.startHeartbeat(o);break;case"HEARTBEAT":this.selfPost?.postMessage({type:"HEARTBEAT_ACK",moduleId:s.moduleId});break;case"HEARTBEAT_ACK":if(!i)return;i.heartbeat.count=0;break;default:if(this.messageHandlers.has(s.type)){const e=this.messageHandlers.get(s.type),t=e?.(s,null,this.selfPost);if(!1===t)return}}}loadModule(e){e.forEach((e=>{let s=new MessageChannel,t=e.getAttribute("moduleId");if(console.log("loadModule",t,e.contentWindow.location),t){if(this.modules.has(t)){const e=this.modules.get(t);e&&e.status}}else t=this.generateUUID(),e.setAttribute("moduleId",t),console.log("loadModule2",t,e.contentWindow.location),s.port1.onmessage=this.receiveMessageScheduler.bind(this),s.port1.onmessageerror=e=>{console.error("receiveMessageScheduler",e)},this.modules.set(t,{port:s.port1,status:"Pending",heartbeat:{lastHeartbeat:Date.now(),timer:null,count:0}}),e.contentWindow.postMessage({type:"INIT_MODULE",moduleId:t,msg:"初始化消息, 等待注册确认!"},"*",[s.port2])}))}receiveMessage(e){if(!e.ports.length)return;console.log("receiveMessage--------",e);const s=e.data,t=e.ports[0];this.receiveMessageScheduler({data:s,port:t})}generateUUID(){return Math.random().toString(36).slice(2,9)}addMessageHandler(e,s){if("function"!=typeof s)throw new Error("处理函数必须是一个函数");return this.messageHandlers.set(e,s),this}removeMessageHandler(e){return this.messageHandlers.delete(e),this}getRegisteredMessageTypes(){return Array.from(this.messageHandlers.keys())}getRegisteredModules(){return Array.from(this.modules.keys())}startHeartbeat(e){this.heartbeatTimers.has(e)&&clearInterval(this.heartbeatTimers.get(e));const s=setInterval((()=>{if(this.modules.has(e)){const s=this.modules.get(e);"Listen"===s.status&&(s.port.postMessage({type:"HEARTBEAT",moduleId:e}),s.heartbeat.count++,s.heartbeat.count>=3&&(this.stopHeartbeat(e),s.status="Disconnected",console.warn(`模块 ${e} 心跳超时,已断开连接`)))}else this.stopHeartbeat(e)}),this.heartbeatInterval);this.heartbeatTimers.set(e,s)}stopHeartbeat(e){this.heartbeatTimers.has(e)&&(clearInterval(this.heartbeatTimers.get(e)),this.heartbeatTimers.delete(e))}registerDefaultHandlers(){this.addMessageHandler("MODULE_MESSAGE",((e,s,t)=>{if(e.ackId){if(this.msgHistory.set(e.ackId,{moduleId:s,msg:e.message,time:Date.now()}),this.msgHistory.size>100){const e=Array.from(this.msgHistory.keys())[0];this.msgHistory.delete(e)}t&&t.postMessage({type:"MODULE_ACK",moduleId:s,ackId:e.ackId})}}))}}class t extends s{constructor(e){super(e),this.pendingPromises=new Map,this.multiResponsePromises=new Map,this.listenToMessageReceipts=new Map,this.manualReplyCallBack=new Map,this.addMessageHandler("PROMISE_MSG",this.promise_msg_handler.bind(this)),this.addMessageHandler("PROMISE_MSG_ACK",this.promise_msg_ack_handler.bind(this))}sendMessage(e,s){let t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{timeoutMs:-1,ackId:void 0};if(!this.modules.has(e))return Promise.reject(new Error("模块不存在"));const o=this.modules.get(e);if("Listen"!==o?.status)return Promise.reject(new Error("模块未监听"));const i=t.ackId??this.generateUUID();return new Promise(((r,a)=>{let n;-1!==t.timeoutMs&&(n=setTimeout((()=>{this.pendingPromises.has(i)&&(a(new Error("消息回执超时")),this.pendingPromises.delete(i))}),t.timeoutMs)),this.pendingPromises.set(i,{resolve:r,reject:a,timeout:n}),o.port.postMessage({type:"PROMISE_MSG",moduleId:e,message:s,ackId:i})}))}broadcastMessage(e){let s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{timeoutMs:-1,ackId:void 0};if(0===this.modules.size)return Promise.reject(new Error("没有可用的子模块"));const t=[],o={};return this.modules.forEach(((i,r)=>{if("Listen"===i.status){const i=this.sendMessage(r,e,s).then((e=>(o[r]={success:!0,result:e},{moduleId:r,success:!0,result:e}))).catch((e=>(o[r]={success:!1,error:e.message},{moduleId:r,success:!1,error:e.message})));t.push(i)}})),Promise.all(t).then((()=>({allSuccess:Object.values(o).every((e=>e.success)),results:o})))}sendToParent(e){let s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{timeoutMs:-1,ackId:void 0};if(!this.selfPost)return Promise.reject(new Error("父模块通信端口未初始化"));const t=s.ackId??this.generateUUID();return new Promise(((o,i)=>{let r;-1!==s.timeoutMs&&(r=setTimeout((()=>{this.pendingPromises.has(t)&&(i(new Error("消息回执超时")),this.pendingPromises.delete(t))}),s.timeoutMs)),this.pendingPromises.set(t,{resolve:o,reject:i,timeout:r}),this.selfPost?.postMessage({type:"PROMISE_MSG",message:e,moduleId:this.selfModuleId,ackId:t})}))}handleAck(e,s){if(this.pendingPromises.has(e)){const{resolve:t,timeout:o}=this.pendingPromises.get(e);clearTimeout(o),t(s),this.pendingPromises.delete(e)}if(this.multiResponsePromises.has(e)){const{callback:t}=this.multiResponsePromises.get(e);t(s)}}async promise_msg_handler(e,s,t){const o=e.message.action??"msg",i=e.type+o;if(this.listenToMessageReceipts.has(i)){const o=this.listenToMessageReceipts.get(i),r=await o(e,s,t);if(console.log("promise_msg_handler",e),console.log("promise_msg_handler",r),!1===r)return void this.manualReplyCallBack.set(e.ackId,(s=>{console.log("manualReplyCallBack",s),this.promise_msg_handler_common(e,s)}));this.promise_msg_handler_common(e,r)}}promise_msg_handler_common(e,s){if(console.log("promise_msg_handler_common",e),e.moduleId===this.selfModuleId)this.selfPost?.postMessage({type:"PROMISE_MSG_ACK",moduleId:this.selfModuleId,message:s,ackId:e.ackId});else{const t=this.modules.get(e.moduleId);t&&t.port.postMessage({type:"PROMISE_MSG_ACK",moduleId:e.moduleId,message:s,ackId:e.ackId})}}promise_msg_ack_handler(e,s,t){console.log("promise_msg_ack_handler",e,s,t),this.handleAck(e.ackId,e)}addMessageActionFn(e){let s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"msg",t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"PROMISE_MSG";return this.listenToMessageReceipts.set(t+s,e),this}}e.ModuleCommunicationCore=s,e.ModuleCommunicationCustom=t,e.init=()=>new t}));