@pulsebeam/peer 0.0.21 → 0.0.22
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/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
@@ -33,5 +33,5 @@ t=0 0\r
|
|
33
33
|
a=extmap-allow-mixed`)!==-1){let s=i.sdp.split(`
|
34
34
|
`).filter(a=>a.trim()!=="a=extmap-allow-mixed").join(`
|
35
35
|
`);e.RTCSessionDescription&&i instanceof e.RTCSessionDescription?arguments[0]=new e.RTCSessionDescription({type:i.type,sdp:s}):i.sdp=s}return n.apply(this,arguments)}}function E(e,t){if(!(e.RTCPeerConnection&&e.RTCPeerConnection.prototype))return;let n=e.RTCPeerConnection.prototype.addIceCandidate;!n||n.length===0||(e.RTCPeerConnection.prototype.addIceCandidate=function(){return arguments[0]?(t.browser==="chrome"&&t.version<78||t.browser==="firefox"&&t.version<68||t.browser==="safari")&&arguments[0]&&arguments[0].candidate===""?Promise.resolve():n.apply(this,arguments):(arguments[1]&&arguments[1].apply(null),Promise.resolve())})}function _(e,t){if(!(e.RTCPeerConnection&&e.RTCPeerConnection.prototype))return;let n=e.RTCPeerConnection.prototype.setLocalDescription;!n||n.length===0||(e.RTCPeerConnection.prototype.setLocalDescription=function(){let i=arguments[0]||{};if(typeof i!="object"||i.type&&i.sdp)return n.apply(this,arguments);if(i={type:i.type,sdp:i.sdp},!i.type)switch(this.signalingState){case"stable":case"have-local-offer":case"have-remote-pranswer":i.type="offer";break;default:i.type="answer";break}return i.sdp||i.type!=="offer"&&i.type!=="answer"?n.apply(this,[i]):(i.type==="offer"?this.createOffer:this.createAnswer).apply(this).then(a=>n.apply(this,[a]))})}var jt=it(ke());function ht({window:e}={},t={shimChrome:!0,shimFirefox:!0,shimSafari:!0}){let n=L,r=dt(e),i={browserDetails:r,commonShim:Ie,extractVersion:P,disableLog:ct,disableWarnings:pt,sdp:jt};switch(r.browser){case"chrome":if(!U||!j||!t.shimChrome)return n("Chrome shim is not included in this adapter release."),i;if(r.version===null)return n("Chrome shim can not determine version, not shimming."),i;n("adapter.js shimming chrome."),i.browserShim=U,E(e,r),_(e,r),A(e,r),re(e,r),j(e,r),ne(e,r),oe(e,r),ie(e,r),se(e,r),ae(e,r),x(e,r),z(e,r),B(e,r),k(e,r),I(e,r),K(e,r);break;case"firefox":if(!G||!N||!t.shimFirefox)return n("Firefox shim is not included in this adapter release."),i;n("adapter.js shimming firefox."),i.browserShim=G,E(e,r),_(e,r),F(e,r),N(e,r),ce(e,r),le(e,r),pe(e,r),de(e,r),ue(e,r),me(e,r),fe(e,r),he(e,r),ge(e,r),x(e,r),B(e,r),k(e,r),I(e,r);break;case"safari":if(!q||!t.shimSafari)return n("Safari shim is not included in this adapter release."),i;n("adapter.js shimming safari."),i.browserShim=q,E(e,r),_(e,r),ve(e,r),be(e,r),Se(e,r),Ce(e,r),ye(e,r),Te(e,r),Re(e,r),Pe(e,r),x(e,r),z(e,r),k(e,r),I(e,r),K(e,r);break;default:n("Unsupported browser!");break}return i}var Ut=ht({window:typeof window>"u"?void 0:window}),M=Ut;var gt=require("@protobuf-ts/runtime-rpc"),h=require("@protobuf-ts/runtime"),Ze=(s=>(s[s.UNSPECIFIED=0]="UNSPECIFIED",s[s.OFFER=1]="OFFER",s[s.ANSWER=2]="ANSWER",s[s.PRANSWER=3]="PRANSWER",s[s.ROLLBACK=4]="ROLLBACK",s))(Ze||{}),Ee=class extends h.MessageType{constructor(){super("pulsebeam.v1.PrepareReq",[])}},Ft=new Ee,_e=class extends h.MessageType{constructor(){super("pulsebeam.v1.PrepareResp",[{no:1,name:"ice_servers",kind:"message",repeat:1,T:()=>Gt}])}},Nt=new _e,Me=class extends h.MessageType{constructor(){super("pulsebeam.v1.IceServer",[{no:1,name:"urls",kind:"scalar",repeat:2,T:9},{no:2,name:"username",kind:"scalar",opt:!0,T:9},{no:3,name:"credential",kind:"scalar",opt:!0,T:9}])}},Gt=new Me,De=class extends h.MessageType{constructor(){super("pulsebeam.v1.SendReq",[{no:1,name:"msg",kind:"message",T:()=>Ct}])}},qt=new De,Oe=class extends h.MessageType{constructor(){super("pulsebeam.v1.SendResp",[])}},zt=new Oe,Le=class extends h.MessageType{constructor(){super("pulsebeam.v1.RecvReq",[{no:1,name:"src",kind:"message",T:()=>Ue}])}},Bt=new Le,Ae=class extends h.MessageType{constructor(){super("pulsebeam.v1.RecvResp",[{no:1,name:"msg",kind:"message",T:()=>Ct}])}},Kt=new Ae,je=class extends h.MessageType{constructor(){super("pulsebeam.v1.PeerInfo",[{no:1,name:"group_id",kind:"scalar",T:9},{no:2,name:"peer_id",kind:"scalar",T:9},{no:3,name:"conn_id",kind:"scalar",T:13}])}},Ue=new je,Fe=class extends h.MessageType{constructor(){super("pulsebeam.v1.Message",[{no:1,name:"header",kind:"message",T:()=>Vt},{no:2,name:"payload",kind:"message",T:()=>Jt}])}},Ct=new Fe,Ne=class extends h.MessageType{constructor(){super("pulsebeam.v1.MessagePayload",[{no:1,name:"signal",kind:"message",oneof:"payloadType",T:()=>Ht},{no:2,name:"join",kind:"message",oneof:"payloadType",T:()=>Xt},{no:3,name:"bye",kind:"message",oneof:"payloadType",T:()=>Qt},{no:4,name:"ack",kind:"message",oneof:"payloadType",T:()=>Zt},{no:5,name:"ping",kind:"message",oneof:"payloadType",T:()=>$t}])}},Jt=new Ne,Ge=class extends h.MessageType{constructor(){super("pulsebeam.v1.MessageHeader",[{no:1,name:"src",kind:"message",T:()=>Ue},{no:2,name:"dst",kind:"message",T:()=>Ue},{no:7,name:"seqnum",kind:"scalar",T:13},{no:8,name:"reliable",kind:"scalar",T:8}])}},Vt=new Ge,qe=class extends h.MessageType{constructor(){super("pulsebeam.v1.Signal",[{no:1,name:"generation_counter",kind:"scalar",T:13},{no:9,name:"sdp",kind:"message",oneof:"data",T:()=>Yt},{no:10,name:"ice_candidate",kind:"message",oneof:"data",T:()=>yt},{no:11,name:"ice_candidate_batch",kind:"message",oneof:"data",T:()=>Wt}])}},Ht=new qe,ze=class extends h.MessageType{constructor(){super("pulsebeam.v1.Sdp",[{no:1,name:"kind",kind:"enum",T:()=>["pulsebeam.v1.SdpKind",Ze,"SDP_KIND_"]},{no:2,name:"sdp",kind:"scalar",T:9}])}},Yt=new ze,Be=class extends h.MessageType{constructor(){super("pulsebeam.v1.ICECandidateBatch",[{no:1,name:"candidates",kind:"message",repeat:1,T:()=>yt}])}},Wt=new Be,Ke=class extends h.MessageType{constructor(){super("pulsebeam.v1.ICECandidate",[{no:1,name:"candidate",kind:"scalar",T:9},{no:2,name:"sdp_m_line_index",kind:"scalar",opt:!0,T:13},{no:3,name:"sdp_mid",kind:"scalar",opt:!0,T:9},{no:4,name:"username",kind:"scalar",opt:!0,T:9},{no:5,name:"password",kind:"scalar",opt:!0,T:9}])}},yt=new Ke,Je=class extends h.MessageType{constructor(){super("pulsebeam.v1.Join",[])}},Xt=new Je,Ve=class extends h.MessageType{constructor(){super("pulsebeam.v1.Bye",[])}},Qt=new Ve,He=class extends h.MessageType{constructor(){super("pulsebeam.v1.Ack",[{no:1,name:"ack_ranges",kind:"message",repeat:1,T:()=>wt}])}},Zt=new He,Ye=class extends h.MessageType{constructor(){super("pulsebeam.v1.Ping",[])}},$t=new Ye,We=class extends h.MessageType{constructor(){super("pulsebeam.v1.AckRange",[{no:1,name:"seqnum_start",kind:"scalar",T:13},{no:2,name:"seqnum_end",kind:"scalar",T:13}])}},wt=new We,Xe=class extends h.MessageType{constructor(){super("pulsebeam.v1.DataChannel",[{no:10,name:"heartbeat",kind:"message",oneof:"payload",T:()=>er}])}},Pr=new Xe,Qe=class extends h.MessageType{constructor(){super("pulsebeam.v1.DataChannelHeartbeat",[])}},er=new Qe,J=new gt.ServiceType("pulsebeam.v1.Signaling",[{name:"Prepare",options:{},I:Ft,O:Nt},{name:"Send",options:{},I:qt,O:zt},{name:"Recv",serverStreaming:!0,options:{},I:Bt,O:Kt}]);var V=require("@protobuf-ts/runtime-rpc"),H=class{constructor(t){this._transport=t;this.typeName=J.typeName;this.methods=J.methods;this.options=J.options}prepare(t,n){let r=this.methods[0],i=this._transport.mergeOptions(n);return(0,V.stackIntercept)("unary",this._transport,r,i,t)}send(t,n){let r=this.methods[1],i=this._transport.mergeOptions(n);return(0,V.stackIntercept)("unary",this._transport,r,i,t)}recv(t,n){let r=this.methods[2],i=this._transport.mergeOptions(n);return(0,V.stackIntercept)("serverStreaming",this._transport,r,i,t)}};function $e(e,t){return new Promise(n=>{let r=setTimeout(()=>n(!0),e);t&&t.addEventListener("abort",()=>{clearTimeout(r),n(!1)})})}function Y(...e){let t=new AbortController,n=()=>{t.abort();for(let r of e)r.removeEventListener("abort",n)};for(let r of e)r.addEventListener("abort",n);return t.signal}async function D(e,t){let{maxRetries:n,baseDelay:r,maxDelay:i,jitterFactor:s=.3,isRecoverable:a=()=>!0,abortSignal:o}=t,d=0;for(;(d<=n||n<0)&&!o?.aborted;)try{return await e()}catch(c){if(!a(c)||(d++,n>=0&&d>n))throw c;let p=tr(d,r,i,s);await $e(p,o).catch(()=>{})}if(o?.aborted)return null;throw new Error("Retry failed: max retries exceeded")}function tr(e,t,n,r){let i=Math.min(t*2**(e-1),n),s=Math.random()*r*i;return i+s}var St=9e5,Rt=50,we=1e3;var rr=$e,nr=e=>{let t;do{let n=new Uint32Array(1);crypto.getRandomValues(n),t=n[0]}while(t>=0&&t<e);return t},ir=e=>!0,et=class{constructor(t){this.onmsg=async t=>{};this.logger=t.sub("queue"),this.map=new Map,this.emitted=new Map,this.unreliable=[],this.processing=!1}enqueue(t){if(!t.header?.reliable)this.unreliable.push(t);else{let n=t.header.seqnum;if(this.map.has(n)||this.emitted.has(n))return;this.map.set(n,[performance.now(),t])}this.processNext()}async processNext(){if(this.processing)return;let t=this.unreliable.pop();if(!t){let n=this.map.entries().next().value;if(!n)return;let[r,i]=n;this.map.delete(r),this.emitted.set(r,i);let[s,a]=i;if(!a.header)return;t=a}this.processing=!0;try{await this.onmsg(t)}catch(n){let r={msg:t};n instanceof Error&&(r.err=n),this.logger.error("error processing message",r)}this.processing=!1,this.processNext()}},W=class{constructor(t,n){this.client=t;this.opts=n;this.onstream=t=>{};this.onclosed=t=>{};this.handleControlMessage=t=>{switch(t.payloadType.oneofKind){case"ping":this.logger.debug("received ping");break;default:this.logger.warn("received unknown control message",{payload:t});break}};this.handleMessages=t=>{if(this.logger.debug("received",{msg:t}),this.abort.signal.aborted)return;if(!t.header)return t.payload?this.handleControlMessage(t.payload):void 0;let n=t.header.src,r=t.header.dst;if(!n||!r)return;if(r.connId>=16&&r.connId!=this.info.connId){this.logger.warn("received messages from a stale connection, ignoring",{receivedConnID:r.connId});return}let i=null;for(let s of this.streams)if(n.groupId===s.other.groupId&&n.peerId===s.other.peerId&&n.connId===s.other.connId){i=s;break}if(!i){if(n.peerId==this.info.peerId){this.logger.warn("loopback detected, ignoring messages");return}this.logger.debug(`session not found, creating one for ${n.peerId}:${n.connId}`),i=new tt(this,this.info,n,this.logger),this.streams.push(i),this.onstream(i)}i.enqueue(t)};this.asleep=n.asleep||rr,this.randUint32=n.randUint32||nr,this.isRecoverable=n.isRecoverable||ir,this.info={groupId:n.groupId,peerId:n.peerId,connId:this.randUint32(16)},this.abort=new AbortController,this.logger=n.logger.sub("transport",{info:this.info}),this.streams=[]}async listen(){let t={abort:this.abort.signal,timeout:St},n={baseDelay:Rt,maxDelay:we,maxRetries:-1,abortSignal:this.abort.signal,isRecoverable:this.isRecoverable};for(;!this.abort.signal.aborted;)try{await D(async()=>{let r=this.client.recv({src:this.info},t);r.responses.onMessage(i=>!!i.msg&&this.handleMessages(i.msg)),await r},n)}catch(r){this.logger.error("unrecoverable error, force closing",{err:r}),this.close();return}this.logger.debug("poll loop is closed")}async close(t){this.abort.signal.aborted||(t=t||"transport is closed",await Promise.all(this.streams.map(n=>n.close(t))),this.abort.abort(t),this.logger.debug("transport is now closed",{reason:t}),this.streams=[],this.onclosed(t))}removeStream(t){this.streams=this.streams.filter(n=>n!==t)}async connect(t,n,r){let i={payloadType:{oneofKind:"join",join:{}}},s={src:this.info,dst:{groupId:t,peerId:n,connId:0},seqnum:0,reliable:!1},a=!1,o=Y(r,this.abort.signal);for(;!o.aborted&&!a;)await this.send(o,{header:s,payload:i}),await this.asleep(we,o).catch(()=>{}),a=!!this.streams.find(d=>d.other.groupId===t&&d.other.peerId===n)}async send(t,n){let r=Y(t,this.abort.signal),i={abort:r,timeout:St},s={baseDelay:Rt,maxDelay:we,maxRetries:-1,abortSignal:r,isRecoverable:this.isRecoverable};try{if(await D(async()=>await this.client.send({msg:n},i),s)===null){this.logger.warn("aborted, message dropped from sending",{msg:n});return}return}catch(a){this.logger.error("unrecoverable error, force closing",{err:a}),this.close();return}}},tt=class{constructor(t,n,r,i){this.transport=t;this.info=n;this.other=r;this.onsignal=async t=>{};this.onclosed=t=>{};this.logger=i.sub("stream",{other:r}),this.abort=new AbortController,this.recvq=new et(this.logger),this.recvq.onmsg=s=>this.handleMessage(s),this.lastSeqnum=0}createSignal(...t){return Y(this.abort.signal,...t)}enqueue(t){if(this.abort.signal.aborted){this.logger.warn("received a message in closed state, ignoring new messages.");return}this.recvq.enqueue(t)}async send(t,n,r){r||(r=this.abort.signal);let i={header:{src:this.transport.info,dst:this.other,seqnum:this.lastSeqnum,reliable:n},payload:{...t}};this.lastSeqnum++,await this.transport.send(r,i)}async handleMessage(t){if(!t.payload){this.logger.warn("payload is missing from the stream message",{msg:t});return}switch(t.payload.payloadType.oneofKind){case"bye":this.close("received bye",!0);return;case"signal":this.onsignal(t.payload.payloadType.signal);return;case"join":return;default:this.logger.warn("unhandled payload type",{msg:t});return}}async close(t,n){this.abort.signal.aborted||(t=t||"session is closed",n||await this.send({payloadType:{oneofKind:"bye",bye:{}}},!1).catch(r=>this.logger.warn("failed to send bye",{e:r})),this.abort.abort(t),this.transport.removeStream(this),this.onclosed(t),this.logger.debug("sent bye to the other peer",{reason:t}))}};var sr={DEBUG:console.debug,INFO:console.info,WARN:console.warn,ERROR:console.error},vt={DEBUG:e=>console.debug(X(e)),INFO:e=>console.info(X(e)),WARN:e=>console.warn(X(e)),ERROR:e=>console.error(X(e))};function Tt(e,t,n="root",r=new Set){let i=".";if(!r.has(e)){r.add(e);for(let s in e)if(typeof e[s]=="object"&&e[s]!==null){let a=n+i+s;Tt(e[s],t,a,r)}else{let a=t[n]||[];a.push(`${s}=${e[s]}`),t[n]=a}}}function X(e){let t={};Tt(e,t);let n=[];for(let r in t)n.push(`[${r}] ${t[r].join(" ")}`);return n.join(`
|
36
|
-
`)}var Q=class e{constructor(t,n,r){this.name=t;n||(n={}),r||(r=sr),this.sink=r,this.obj={...n,name:t}}log(t,n,r){let i=r||{};t({ts:Date.now(),message:n,...this.obj,...i})}debug(t,n){this.log(this.sink.DEBUG,t,n)}info(t,n){this.log(this.sink.INFO,t,n)}warn(t,n){this.log(this.sink.WARN,t,n)}error(t,n){this.log(this.sink.ERROR,t,n)}sub(t,n){return n||(n={}),new e(this.name+"."+t,{...this.obj,...n},this.sink)}};var or=2,bt=5e3;function ar(e){return{candidate:e.candidate,sdpMid:e.sdpMid,sdpMLineIndex:e.sdpMLineIndex,usernameFragment:e.password}}function cr(e){switch(e){case 1:return"offer";case 2:return"answer";case 3:return"pranswer";case 4:return"rollback";default:throw new Error(`unexpected kind: ${e}`)}}function Pt(e){switch(e){case"offer":return 1;case"answer":return 2;case"pranswer":return 3;case"rollback":return 4;default:throw new Error(`unexpected sdp type: ${e}`)}}var Z=class{constructor(t,n){this.stream=t;this.ondatachannel=()=>{};this.onconnectionstatechange=()=>{};this.ontrack=()=>{};this.triggerIceRestart=()=>{if(!this.impolite)return;let t=performance.now()-this.lastIceRestart;if(t<bt){let n=bt-t,r=window.setTimeout(()=>{this.triggerIceRestart(),this.timers=this.timers.filter(i=>i===r)},n);return}if(this.pc.connectionState!=="connected"){if(this.iceRestartCount>=or){this.close("detected sustained network failure");return}this.logger.debug("triggered ICE restart"),this.pc.restartIce(),this.generationCounter++,this.iceRestartCount++,this.lastIceRestart=performance.now()}};this.sendSignal=t=>{this.stream.send({payloadType:{oneofKind:"signal",signal:{...t,generationCounter:this.generationCounter}}},!0)};this.handleSignal=async t=>{if(t.generationCounter<this.generationCounter){this.logger.warn("detected staled generationCounter signals, ignoring");return}this.addCandidates(t);let n=t.data;if(t.generationCounter>this.generationCounter){if(this.logger.debug("detected new generationCounter",{otherGenerationCounter:t.generationCounter,generationCounter:this.generationCounter,msg:n}),n.oneofKind==="iceCandidate"){this.logger.warn("expecting an offer but got ice candidates during an ICE restart, adding to pending.",{msg:n});return}this.generationCounter=t.generationCounter}if(n.oneofKind!="sdp")return;let r=n.sdp;this.logger.debug("received a SDP signal",{sdpKind:r.kind});let i=r.kind===1&&(this.makingOffer||this.pc.signalingState!=="stable");if(this.impolite&&i){this.logger.debug("ignored offer");return}if(this.logger.debug("creating an answer"),await this.pc.setRemoteDescription({type:cr(r.kind),sdp:r.sdp}),r.kind===1){if(await this.pc.setLocalDescription(),!this.pc.localDescription){this.logger.error("unexpected null local description");return}this.sendSignal({data:{oneofKind:"sdp",sdp:{kind:Pt(this.pc.localDescription.type),sdp:this.pc.localDescription.sdp}}})}this.checkPendingCandidates()};this.checkPendingCandidates=()=>{if(!["stable","have-local-offer","have-remote-offer"].includes(this.pc.signalingState)||!this.pc.remoteDescription){this.logger.debug("wait for adding pending candidates",{signalingState:this.pc.signalingState,iceConnectionState:this.pc.iceConnectionState,connectionState:this.pc.connectionState,remoteDescription:this.pc.remoteDescription,pendingCandidates:this.pendingCandidates.length});return}for(let n of this.pendingCandidates)!n.candidate||n.candidate===""||(this.pc.addIceCandidate(n).catch(r=>{this.logger.warn("failed to add candidate, skipping.",{candidate:n,e:r})}),this.logger.debug(`added ice: ${n.candidate}`));this.pendingCandidates=[]};this.pc=new RTCPeerConnection(n),this.makingOffer=!1,this.pendingCandidates=[],this.stream.info.connId===this.stream.other.connId?this.impolite=this.stream.info.peerId>this.stream.other.peerId:this.impolite=this.stream.info.connId>this.stream.other.connId,this.abort=new AbortController,this.logger=t.logger.sub("session",{role:this.impolite?"impolite":"polite"}),this.generationCounter=0,this.iceRestartCount=0,this.lastIceRestart=0,this.timers=[],this._connectionState="new",this.iceBatcher=new rt(this.logger,100,s=>this.sendLocalIceCandidates(s)),t.onsignal=s=>this.handleSignal(s),t.onclosed=s=>this.close(s),this.pc.oniceconnectionstatechange=async()=>{let s=await this.pc.getStats(),a=[],o=[],d=[];s.forEach(c=>{c.type==="candidate-pair"?a.push(c):c.type==="local-candidate"?o.push(c):c.type==="remote-candidate"&&d.push(c)}),this.logger.debug("iceconnectionstate changed",{connectionstate:this.pc.connectionState,iceconnectionstate:this.pc.iceConnectionState,local:o,remote:d,pair:a,pending:this.pendingCandidates})};let r=performance.now();this.pc.onconnectionstatechange=s=>{switch(this.logger.debug("connectionstate changed",{connectionstate:this.pc.connectionState,iceconnectionstate:this.pc.iceConnectionState}),this.setConnectionState(this.pc.connectionState,s),this.pc.connectionState){case"connecting":r=performance.now();break;case"connected":{let a=performance.now()-r;this.logger.debug(`it took ${a}ms to connect`),this.iceRestartCount=0;break}case"disconnected":this.triggerIceRestart();break;case"failed":this.triggerIceRestart();break;case"closed":break}};let i=!0;this.pc.onnegotiationneeded=async()=>{if(i){if(!this.impolite){this.stream.send({payloadType:{oneofKind:"join",join:{}}},!0);return}i=!1}try{if(this.makingOffer=!0,this.logger.debug("creating an offer"),await this.pc.setLocalDescription(),!this.pc.localDescription)throw new Error("expect localDescription to be not empty");this.sendSignal({data:{oneofKind:"sdp",sdp:{kind:Pt(this.pc.localDescription.type),sdp:this.pc.localDescription.sdp}}})}catch(s){s instanceof Error&&this.logger.error("failed in negotiating",{err:s})}finally{this.makingOffer=!1}},this.pc.onicecandidate=({candidate:s})=>{this.iceBatcher.addCandidate(s)},this.pc.ondatachannel=(...s)=>{this.ondatachannel&&this.ondatachannel(...s)},this.pc.ontrack=(...s)=>{this.ontrack&&this.ontrack(...s)}}addTrack(...t){return this.pc.addTrack(...t)}removeTrack(...t){return this.pc.removeTrack(...t)}createDataChannel(...t){return this.pc.createDataChannel(...t)}get connectionState(){return this.pc.connectionState}get closeReason(){return this._closeReason}get other(){return{groupId:this.stream.other.groupId,peerId:this.stream.other.peerId,connId:this.stream.other.connId}}close(t){if(this.abort.signal.aborted)return;this.abort.abort(t);for(let r of this.timers)clearTimeout(r);this.timers=[],this.iceBatcher.close(),this.stream.close(),this._closeReason=t,this.pc.close();let n=new Event("connectionstatechange");this.setConnectionState("closed",n),this.logger.debug("session closed",{connectionState:this.connectionState})}sendLocalIceCandidates(t){let n=[];for(let r of t){let i={candidate:"",sdpMLineIndex:0,sdpMid:""};i.candidate=r.candidate,i.sdpMLineIndex=r.sdpMLineIndex??void 0,i.sdpMid=r.sdpMid??void 0,i.username=r.usernameFragment??void 0,n.push(i)}this.sendSignal({data:{oneofKind:"iceCandidateBatch",iceCandidateBatch:{candidates:n}}})}setConnectionState(t,n){t!==this._connectionState&&this.onconnectionstatechange&&this.onconnectionstatechange(n)}addCandidates(t){let n=[];if(t.data.oneofKind==="iceCandidate")n.push(t.data.iceCandidate);else if(t.data.oneofKind==="iceCandidateBatch")n.push(...t.data.iceCandidateBatch.candidates);else return;this.pendingCandidates.push(...n.map(r=>ar(r))),this.checkPendingCandidates()}},rt=class{constructor(t,n,r){this.candidates=[];this.timeoutId=null;this.addCandidate=t=>{if(!t||t.candidate===""){this.logger.debug("ice gathering is finished, force flush local candidates"),this.flushCandidates();return}this.logger.debug("onicecandidate",{candidate:t}),this.candidates.push(t),this.timeoutId?(clearTimeout(this.timeoutId),this.timeoutId=setTimeout(this.flushCandidates,this.delayMs)):this.timeoutId=setTimeout(this.flushCandidates,this.delayMs)};this.flushCandidates=()=>{this.candidates.length>0&&(this.onIceCandidates(this.candidates),this.candidates=[]),this.timeoutId=null};this.flush=()=>{this.timeoutId&&clearTimeout(this.timeoutId),this.flushCandidates()};this.close=()=>{this.timeoutId&&clearTimeout(this.timeoutId)};this.logger=t.sub("icebatcher"),this.delayMs=n,this.onIceCandidates=r}};var kt=require("@protobuf-ts/runtime-rpc"),y=require("@protobuf-ts/grpcweb-transport");var It=require("jwt-decode"),pr="https://cloud.pulsebeam.dev/grpc";var $=class{constructor(t,n,r,i){this.onsession=t=>{};this.onstatechange=()=>{};this.peerId=r.peerId,this.logger=t.sub("peer",{peerId:this.peerId}),this.sessions=[],this._state="new";let s={bundlePolicy:"balanced",iceTransportPolicy:r.forceRelay?"relay":"all",iceCandidatePoolSize:0,iceServers:r.iceServers};this.transport=new W(n,{enableDiscovery:!1,groupId:r.groupId,peerId:r.peerId,logger:this.logger,isRecoverable:i}),this.transport.onstream=a=>{let o=new Z(a,s);this.sessions.push(o),this.onsession(o)},this.transport.onclosed=()=>{this.close()}}start(){if(this._state==="closed")throw new Error("peer is already closed");this.transport.listen()}async close(){this.sessions=[],await this.transport.close(),this.setState("closed")}connect(t,n,r){return this.transport.connect(t,n,r)}get state(){return this._state}setState(t){t!==this._state&&(this._state=t,this.onstatechange())}},dr=[y.GrpcStatusCode[y.GrpcStatusCode.PERMISSION_DENIED],y.GrpcStatusCode[y.GrpcStatusCode.INVALID_ARGUMENT],y.GrpcStatusCode[y.GrpcStatusCode.ABORTED],y.GrpcStatusCode[y.GrpcStatusCode.NOT_FOUND],y.GrpcStatusCode[y.GrpcStatusCode.UNAUTHENTICATED]];function xt(e){return e instanceof Error?e instanceof kt.RpcError?!dr.includes(e.code):!0:!1}async function lr(e){let t=e.token,n=new y.GrpcWebFetchTransport({baseUrl:e.baseUrl||pr,sendJson:!1,format:"binary",jsonOptions:{emitDefaultValues:!0,enumAsInteger:!0,ignoreUnknownFields:!0},interceptors:[{interceptUnary(c,p,u,m){return m.meta||(m.meta={}),m.meta.Authorization=`Bearer ${t}`,c(p,u,m)}}]}),r=new H(n),i=await D(async()=>await r.prepare({}),{baseDelay:50,maxDelay:1e3,maxRetries:5,isRecoverable:xt});if(i===null)throw new Error("createPeer aborted");let s=[...e.iceServers||[]];for(let c of i.response.iceServers)s.push({urls:c.urls,username:c.username,credential:c.credential});let a=(0,It.jwtDecode)(t),o={...e,iceServers:s,groupId:a.gid,peerId:a.pid};return new $(new Q("pulsebeam",void 0,vt),r,o,xt)}M.disableLog(!1);M.disableWarnings(!1);console.log("UA: ",navigator.userAgent);console.log("webrtc-adapter is enabled",JSON.stringify({shim:M.browserShim,version:M.browserDetails},null,2));0&&(module.exports={Peer,createPeer});
|
36
|
+
`)}var Q=class e{constructor(t,n,r){this.name=t;n||(n={}),r||(r=sr),this.sink=r,this.obj={...n,name:t}}log(t,n,r){let i=r||{};t({ts:Date.now(),message:n,...this.obj,...i})}debug(t,n){this.log(this.sink.DEBUG,t,n)}info(t,n){this.log(this.sink.INFO,t,n)}warn(t,n){this.log(this.sink.WARN,t,n)}error(t,n){this.log(this.sink.ERROR,t,n)}sub(t,n){return n||(n={}),new e(this.name+"."+t,{...this.obj,...n},this.sink)}};var or=1,bt=5e3;function ar(e){return{candidate:e.candidate,sdpMid:e.sdpMid,sdpMLineIndex:e.sdpMLineIndex,usernameFragment:e.password}}function cr(e){switch(e){case 1:return"offer";case 2:return"answer";case 3:return"pranswer";case 4:return"rollback";default:throw new Error(`unexpected kind: ${e}`)}}function Pt(e){switch(e){case"offer":return 1;case"answer":return 2;case"pranswer":return 3;case"rollback":return 4;default:throw new Error(`unexpected sdp type: ${e}`)}}var Z=class{constructor(t,n){this.stream=t;this.ondatachannel=()=>{};this.onconnectionstatechange=()=>{};this.ontrack=()=>{};this.triggerIceRestart=()=>{if(!this.impolite)return;let t=performance.now()-this.lastIceRestart;if(t<bt){let n=bt-t,r=window.setTimeout(()=>{this.triggerIceRestart(),this.timers=this.timers.filter(i=>i===r)},n);return}if(this.pc.connectionState!=="connected"){if(this.iceRestartCount>=or){this.close("detected sustained network failure");return}this.logger.debug("triggered ICE restart"),this.pc.restartIce(),this.generationCounter++,this.iceRestartCount++,this.lastIceRestart=performance.now()}};this.sendSignal=t=>{this.stream.send({payloadType:{oneofKind:"signal",signal:{...t,generationCounter:this.generationCounter}}},!0)};this.handleSignal=async t=>{if(t.generationCounter<this.generationCounter){this.logger.warn("detected staled generationCounter signals, ignoring");return}this.addCandidates(t);let n=t.data;if(t.generationCounter>this.generationCounter){if(this.logger.debug("detected new generationCounter",{otherGenerationCounter:t.generationCounter,generationCounter:this.generationCounter,msg:n}),n.oneofKind==="iceCandidate"){this.logger.warn("expecting an offer but got ice candidates during an ICE restart, adding to pending.",{msg:n});return}this.generationCounter=t.generationCounter}if(n.oneofKind!="sdp")return;let r=n.sdp;this.logger.debug("received a SDP signal",{sdpKind:r.kind});let i=r.kind===1&&(this.makingOffer||this.pc.signalingState!=="stable");if(this.impolite&&i){this.logger.debug("ignored offer");return}if(this.logger.debug("creating an answer"),await this.pc.setRemoteDescription({type:cr(r.kind),sdp:r.sdp}),r.kind===1){if(await this.pc.setLocalDescription(),!this.pc.localDescription){this.logger.error("unexpected null local description");return}this.sendSignal({data:{oneofKind:"sdp",sdp:{kind:Pt(this.pc.localDescription.type),sdp:this.pc.localDescription.sdp}}})}this.checkPendingCandidates()};this.checkPendingCandidates=()=>{if(!["stable","have-local-offer","have-remote-offer"].includes(this.pc.signalingState)||!this.pc.remoteDescription){this.logger.debug("wait for adding pending candidates",{signalingState:this.pc.signalingState,iceConnectionState:this.pc.iceConnectionState,connectionState:this.pc.connectionState,remoteDescription:this.pc.remoteDescription,pendingCandidates:this.pendingCandidates.length});return}for(let n of this.pendingCandidates)!n.candidate||n.candidate===""||(this.pc.addIceCandidate(n).catch(r=>{this.logger.warn("failed to add candidate, skipping.",{candidate:n,e:r})}),this.logger.debug(`added ice: ${n.candidate}`));this.pendingCandidates=[]};this.pc=new RTCPeerConnection(n),this.makingOffer=!1,this.pendingCandidates=[],this.stream.info.connId===this.stream.other.connId?this.impolite=this.stream.info.peerId>this.stream.other.peerId:this.impolite=this.stream.info.connId>this.stream.other.connId,this.abort=new AbortController,this.logger=t.logger.sub("session",{role:this.impolite?"impolite":"polite"}),this.generationCounter=0,this.iceRestartCount=0,this.lastIceRestart=0,this.timers=[],this._connectionState="new",this.iceBatcher=new rt(this.logger,100,s=>this.sendLocalIceCandidates(s)),t.onsignal=s=>this.handleSignal(s),t.onclosed=s=>this.close(s),this.pc.oniceconnectionstatechange=async()=>{let s=await this.pc.getStats(),a=[],o=[],d=[];s.forEach(c=>{c.type==="candidate-pair"?a.push(c):c.type==="local-candidate"?o.push(c):c.type==="remote-candidate"&&d.push(c)}),this.logger.debug("iceconnectionstate changed",{connectionstate:this.pc.connectionState,iceconnectionstate:this.pc.iceConnectionState,local:o,remote:d,pair:a,pending:this.pendingCandidates})};let r=performance.now();this.pc.onconnectionstatechange=s=>{switch(this.logger.debug("connectionstate changed",{connectionstate:this.pc.connectionState,iceconnectionstate:this.pc.iceConnectionState}),this.setConnectionState(this.pc.connectionState,s),this.pc.connectionState){case"connecting":r=performance.now();break;case"connected":{let a=performance.now()-r;this.logger.debug(`it took ${a}ms to connect`),this.iceRestartCount=0;break}case"disconnected":this.triggerIceRestart();break;case"failed":this.close("connection failed");break;case"closed":break}};let i=!0;this.pc.onnegotiationneeded=async()=>{if(i){if(!this.impolite){this.stream.send({payloadType:{oneofKind:"join",join:{}}},!0);return}i=!1}try{if(this.makingOffer=!0,this.logger.debug("creating an offer"),await this.pc.setLocalDescription(),!this.pc.localDescription)throw new Error("expect localDescription to be not empty");this.sendSignal({data:{oneofKind:"sdp",sdp:{kind:Pt(this.pc.localDescription.type),sdp:this.pc.localDescription.sdp}}})}catch(s){s instanceof Error&&this.logger.error("failed in negotiating",{err:s})}finally{this.makingOffer=!1}},this.pc.onicecandidate=({candidate:s})=>{this.iceBatcher.addCandidate(s)},this.pc.ondatachannel=(...s)=>{this.ondatachannel&&this.ondatachannel(...s)},this.pc.ontrack=(...s)=>{this.ontrack&&this.ontrack(...s)}}addTrack(...t){return this.pc.addTrack(...t)}removeTrack(...t){return this.pc.removeTrack(...t)}createDataChannel(...t){return this.pc.createDataChannel(...t)}get connectionState(){return this.pc.connectionState}get closeReason(){return this._closeReason}get other(){return{groupId:this.stream.other.groupId,peerId:this.stream.other.peerId,connId:this.stream.other.connId}}close(t){if(this.abort.signal.aborted)return;this.abort.abort(t);for(let r of this.timers)clearTimeout(r);this.timers=[],this.iceBatcher.close(),this.stream.close(),this._closeReason=t,this.pc.close();let n=new Event("connectionstatechange");this.setConnectionState("closed",n),this.logger.debug("session closed",{connectionState:this.connectionState})}sendLocalIceCandidates(t){let n=[];for(let r of t){let i={candidate:"",sdpMLineIndex:0,sdpMid:""};i.candidate=r.candidate,i.sdpMLineIndex=r.sdpMLineIndex??void 0,i.sdpMid=r.sdpMid??void 0,i.username=r.usernameFragment??void 0,n.push(i)}this.sendSignal({data:{oneofKind:"iceCandidateBatch",iceCandidateBatch:{candidates:n}}})}setConnectionState(t,n){t!==this._connectionState&&this.onconnectionstatechange&&this.onconnectionstatechange(n)}addCandidates(t){let n=[];if(t.data.oneofKind==="iceCandidate")n.push(t.data.iceCandidate);else if(t.data.oneofKind==="iceCandidateBatch")n.push(...t.data.iceCandidateBatch.candidates);else return;this.pendingCandidates.push(...n.map(r=>ar(r))),this.checkPendingCandidates()}},rt=class{constructor(t,n,r){this.candidates=[];this.timeoutId=null;this.addCandidate=t=>{if(!t||t.candidate===""){this.logger.debug("ice gathering is finished, force flush local candidates"),this.flushCandidates();return}this.logger.debug("onicecandidate",{candidate:t}),this.candidates.push(t),this.timeoutId?(clearTimeout(this.timeoutId),this.timeoutId=setTimeout(this.flushCandidates,this.delayMs)):this.timeoutId=setTimeout(this.flushCandidates,this.delayMs)};this.flushCandidates=()=>{this.candidates.length>0&&(this.onIceCandidates(this.candidates),this.candidates=[]),this.timeoutId=null};this.flush=()=>{this.timeoutId&&clearTimeout(this.timeoutId),this.flushCandidates()};this.close=()=>{this.timeoutId&&clearTimeout(this.timeoutId)};this.logger=t.sub("icebatcher"),this.delayMs=n,this.onIceCandidates=r}};var kt=require("@protobuf-ts/runtime-rpc"),y=require("@protobuf-ts/grpcweb-transport");var It=require("jwt-decode"),pr="https://cloud.pulsebeam.dev/grpc";var $=class{constructor(t,n,r,i){this.onsession=t=>{};this.onstatechange=()=>{};this.peerId=r.peerId,this.logger=t.sub("peer",{peerId:this.peerId}),this.sessions=[],this._state="new";let s={bundlePolicy:"balanced",iceTransportPolicy:r.forceRelay?"relay":"all",iceCandidatePoolSize:0,iceServers:r.iceServers};this.transport=new W(n,{enableDiscovery:!1,groupId:r.groupId,peerId:r.peerId,logger:this.logger,isRecoverable:i}),this.transport.onstream=a=>{let o=new Z(a,s);this.sessions.push(o),this.onsession(o)},this.transport.onclosed=()=>{this.close()}}start(){if(this._state==="closed")throw new Error("peer is already closed");this.transport.listen()}async close(){this.sessions=[],await this.transport.close(),this.setState("closed")}connect(t,n,r){return this.transport.connect(t,n,r)}get state(){return this._state}setState(t){t!==this._state&&(this._state=t,this.onstatechange())}},dr=[y.GrpcStatusCode[y.GrpcStatusCode.PERMISSION_DENIED],y.GrpcStatusCode[y.GrpcStatusCode.INVALID_ARGUMENT],y.GrpcStatusCode[y.GrpcStatusCode.ABORTED],y.GrpcStatusCode[y.GrpcStatusCode.NOT_FOUND],y.GrpcStatusCode[y.GrpcStatusCode.UNAUTHENTICATED]];function xt(e){return e instanceof Error?e instanceof kt.RpcError?!dr.includes(e.code):!0:!1}async function lr(e){let t=e.token,n=new y.GrpcWebFetchTransport({baseUrl:e.baseUrl||pr,sendJson:!1,format:"binary",jsonOptions:{emitDefaultValues:!0,enumAsInteger:!0,ignoreUnknownFields:!0},interceptors:[{interceptUnary(c,p,u,m){return m.meta||(m.meta={}),m.meta.Authorization=`Bearer ${t}`,c(p,u,m)}}]}),r=new H(n),i=await D(async()=>await r.prepare({}),{baseDelay:50,maxDelay:1e3,maxRetries:5,isRecoverable:xt});if(i===null)throw new Error("createPeer aborted");let s=[...e.iceServers||[]];for(let c of i.response.iceServers)s.push({urls:c.urls,username:c.username,credential:c.credential});let a=(0,It.jwtDecode)(t),o={...e,iceServers:s,groupId:a.gid,peerId:a.pid};return new $(new Q("pulsebeam",void 0,vt),r,o,xt)}M.disableLog(!1);M.disableWarnings(!1);console.log("UA: ",navigator.userAgent);console.log("webrtc-adapter is enabled",JSON.stringify({shim:M.browserShim,version:M.browserDetails},null,2));0&&(module.exports={Peer,createPeer});
|
37
37
|
//# sourceMappingURL=index.cjs.map
|