UNPKG

rpc-shooter

Version:

A tool library for handling window && iframe && worker communication based on the JSON RPC specification

2 lines (1 loc) 5.76 kB
var C=Object.defineProperty,S=Object.defineProperties;var M=Object.getOwnPropertyDescriptors;var x=Object.getOwnPropertySymbols;var k=Object.prototype.hasOwnProperty,I=Object.prototype.propertyIsEnumerable;var y=(r,n,_)=>n in r?C(r,n,{enumerable:!0,configurable:!0,writable:!0,value:_}):r[n]=_,u=(r,n)=>{for(var _ in n||(n={}))k.call(n,_)&&y(r,_,n[_]);if(x)for(var _ of x(n))I.call(n,_)&&y(r,_,n[_]);return r},N=(r,n)=>S(r,M(n));var h=(r,n,_)=>(y(r,typeof n!="symbol"?n+"":n,_),_);(function(r,n){typeof exports=="object"&&typeof module!="undefined"?n(exports):typeof define=="function"&&define.amd?define(["exports"],n):(r=typeof globalThis!="undefined"?globalThis:r||self,n(r.RPCShooter={}))})(this,function(r){"use strict";const n={CONNECT_TIMEOUT:{code:-32300,message:"Connect timeout"},APPLICATION_ERROR:{code:-32500,message:"Application error"},METHOD_NOT_FOUND:{code:-32601,message:"Method not found"}};class _{constructor(e){h(this,"_currentEndpoint");h(this,"_targetEndpoint");h(this,"_events");h(this,"_originOnmessage");h(this,"_receiveMessage");h(this,"onerror",null);h(this,"config");h(this,"sendAdapter");h(this,"receiveAdapter");this._events={},this._currentEndpoint=e.currentEndpoint,this._targetEndpoint=e.targetEndpoint,this._originOnmessage=null,this.config=e.config,this.receiveAdapter=e.receiveAdapter,this.sendAdapter=e.sendAdapter;const t=s=>{const i=this.receiveAdapter?this.receiveAdapter(s):s.data;if(i&&typeof i.event=="string"){const o=this._events[i.event]||[];if(o.length){o.forEach(c=>{c(...i.args||[])});return}this.onerror&&this.onerror(N(u({},n.METHOD_NOT_FOUND),{data:i}))}};if(this._currentEndpoint.addEventListener){"start"in this._currentEndpoint&&this._currentEndpoint.start&&this._currentEndpoint.start(),this._currentEndpoint.addEventListener("message",t,!1),this._receiveMessage=t;return}this._originOnmessage=this._currentEndpoint.onmessage,this._currentEndpoint.onmessage=s=>{this._originOnmessage&&this._originOnmessage(s),t(s)},this._receiveMessage=this._currentEndpoint.onmessage}emit(e,...t){const s={event:e,args:t},i=this.sendAdapter?this.sendAdapter(s,this._targetEndpoint):{data:s},o=i.data||s,c=this.config?typeof this.config=="function"?this.config(o,this._targetEndpoint)||{}:this.config||{}:{};Array.isArray(i.transfer)&&i.transfer.length&&(c.transfer=i.transfer),this._targetEndpoint.postMessage(o,c)}on(e,t){this._events[e]||(this._events[e]=[]),this._events[e].push(t)}off(e,t){if(!this._events[e])return;if(!t){this._events[e]=[];return}const s=this._events[e]||[];this._events[e]=s.filter(i=>i!==t)}destroy(){if(this._currentEndpoint.removeEventListener){this._currentEndpoint.removeEventListener("message",this._receiveMessage,!1);return}try{this._currentEndpoint.onmessage=this._originOnmessage}catch(e){console.warn(e)}}}const m=class{constructor(e){h(this,"_event");h(this,"_methods",{});h(this,"_timeout",0);h(this,"_$connect",null);this._event=e.event,this._timeout=e.timeout||0,e.methods&&Object.entries(e.methods).forEach(([t,s])=>{this.registerMethod(t,s)}),this._event.onerror=t=>{const{code:s,message:i,data:o}=t;if(o.event&&Array.isArray(o.args)&&o.args.length){const c=o.args[0],a=this._getAckEventName(c.method),d={jsonrpc:"2.0",id:c==null?void 0:c.id,error:{code:s,message:i,data:c}};this._event.emit(a,d)}else console.error(t)},this.connect()}static uuid(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=Math.random()*16|0;return(e=="x"?t:t&3|8).toString(16)})}_getSynEventName(e){return`${m.EVENT.SYN_SIGN}${e}`}_getAckEventName(e){return`${m.EVENT.ACK_SIGN}${e}`}connect(e){return this._$connect?this._$connect:(this._$connect=new Promise((t,s)=>{const i=e||this._timeout;let o;i&&(o=setTimeout(()=>{const l=N(u({},n.TIMEOUT),{data:{timeout:i}});s(l)},i));const c=m.EVENT.CONNECT,a=this._getAckEventName(c),d=this._getSynEventName(c),f=()=>{clearTimeout(o),t()};this._event.on(a,f);const g=()=>{this._event.emit(a),f()};this._event.on(d,g),this._event.emit(d)}),this._$connect)}registerMethod(e,t){if(this._methods[e])throw new Error(`${e} already registered`);this._methods[e]=t;const s=this._getSynEventName(e),i=o=>{const c=this._getAckEventName(e);if(!o.id){t(...o.params);return}Promise.resolve(t(...o.params)).then(a=>{const d={jsonrpc:"2.0",result:a,id:o.id};this._event.emit(c,d)}).catch(a=>{const d={jsonrpc:"2.0",id:o.id,error:{code:(a==null?void 0:a.code)||n.APPLICATION_ERROR.code,message:(a==null?void 0:a.message)||n.APPLICATION_ERROR.message,data:null}};this._event.emit(c,d)})};this._event.on(s,i)}removeMethod(e){this._methods[e]||delete this._methods[e];const t=this._getSynEventName(e);this._event.off(t)}invoke(e,...t){return new Promise((s,i)=>{const o=t[t.length-1],c=o&&typeof o=="object"&&(Reflect.has(o,"isNotify")||Reflect.has(o,"timeout")),a=c?o:{isNotify:!1,timeout:0},d=c?t.slice(0,-1):t,f=this._getSynEventName(e),g=m.uuid(),l={jsonrpc:"2.0",method:e,params:d,id:g};if(this._event.emit(f,l),a.isNotify)s(void 0);else{const T=this._getAckEventName(e),p=a.timeout||this._timeout;let O;p&&(O=setTimeout(()=>{const E=N(u({},n.CONNECT_TIMEOUT),{data:{timeout:p}});i(E)},p));const A=E=>{E.id===g&&(clearTimeout(O),this._event.off(T,A),E.error?i(E.error):s(E.result))};this._event.on(T,A)}})}destroy(){Object.entries(this._methods).forEach(([s])=>{const i=this._getSynEventName(s);this._event.off(i)});const e=this._getAckEventName(m.EVENT.CONNECT),t=this._getSynEventName(m.EVENT.CONNECT);this._event.off(t),this._event.off(e),this._event.destroy&&this._event.destroy()}};let v=m;h(v,"CODES",n),h(v,"EVENT",{SYN_SIGN:"syn:",ACK_SIGN:"ack:",CONNECT:"__rpc_connect_event",SYNC_METHODS:"__rpc_sync_methods_event"}),r.RPC=v,r.RPCCodes=n,r.RPCMessageEvent=_,Object.defineProperty(r,"__esModule",{value:!0}),r[Symbol.toStringTag]="Module"});