UNPKG

@chainsafe/libp2p-yamux

Version:
5 lines (4 loc) 33.3 kB
(function (root, factory) {(typeof module === 'object' && module.exports) ? module.exports = factory() : root.ChainsafeLibp2PYamux = factory()}(typeof self !== 'undefined' ? self : this, function () { "use strict";var ChainsafeLibp2PYamux=(()=>{var tt=Object.defineProperty;var It=Object.getOwnPropertyDescriptor;var At=Object.getOwnPropertyNames;var Ct=Object.prototype.hasOwnProperty;var Lt=(s,t)=>{for(var e in t)tt(s,e,{get:t[e],enumerable:!0})},Dt=(s,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of At(t))!Ct.call(s,n)&&n!==e&&tt(s,n,{get:()=>t[n],enumerable:!(r=It(t,n))||r.enumerable});return s};var Wt=s=>Dt(tt({},"__esModule",{value:!0}),s);var zt={};Lt(zt,{GoAwayCode:()=>p,yamux:()=>Ft});var M=class extends Error{static name="AbortError";constructor(t="The operation was aborted"){super(t),this.name="AbortError"}};var m=class extends Error{static name="InvalidParametersError";constructor(t="Invalid parameters"){super(t),this.name="InvalidParametersError"}};var S=class extends Error{static name="MuxerClosedError";constructor(t="The muxer is closed"){super(t),this.name="MuxerClosedError"}},O=class extends Error{static name="StreamResetError";constructor(t="The stream has been reset"){super(t),this.name="StreamResetError"}},F=class extends Error{static name="StreamStateError";constructor(t="The stream is in an invalid state"){super(t),this.name="StreamStateError"}};var z=class extends Error{static name="TooManyOutboundProtocolStreamsError";constructor(t="Too many outbound protocol streams"){super(t),this.name="TooManyOutboundProtocolStreamsError"}};var ot=Symbol.for("@libp2p/service-capabilities"),qt=Symbol.for("@libp2p/service-dependencies");function V(s){if(s!=null){if(typeof s[Symbol.iterator]=="function")return s[Symbol.iterator]();if(typeof s[Symbol.asyncIterator]=="function")return s[Symbol.asyncIterator]();if(typeof s.next=="function")return s}throw new Error("argument is not an iterator or iterable")}function E(){let s={};return s.promise=new Promise((t,e)=>{s.resolve=t,s.reject=e}),s}var G=class{buffer;mask;top;btm;next;constructor(t){if(!(t>0)||(t-1&t)!==0)throw new Error("Max size for a FixedFIFO should be a power of two");this.buffer=new Array(t),this.mask=t-1,this.top=0,this.btm=0,this.next=null}push(t){return this.buffer[this.top]!==void 0?!1:(this.buffer[this.top]=t,this.top=this.top+1&this.mask,!0)}shift(){let t=this.buffer[this.btm];if(t!==void 0)return this.buffer[this.btm]=void 0,this.btm=this.btm+1&this.mask,t}isEmpty(){return this.buffer[this.btm]===void 0}},D=class{size;hwm;head;tail;constructor(t={}){this.hwm=t.splitLimit??16,this.head=new G(this.hwm),this.tail=this.head,this.size=0}calculateSize(t){return t?.byteLength!=null?t.byteLength:1}push(t){if(t?.value!=null&&(this.size+=this.calculateSize(t.value)),!this.head.push(t)){let e=this.head;this.head=e.next=new G(2*this.head.buffer.length),this.head.push(t)}}shift(){let t=this.tail.shift();if(t===void 0&&this.tail.next!=null){let e=this.tail.next;this.tail.next=null,this.tail=e,t=this.tail.shift()}return t?.value!=null&&(this.size-=this.calculateSize(t.value)),t}isEmpty(){return this.head.isEmpty()}};var et=class extends Error{type;code;constructor(t,e){super(t??"The operation was aborted"),this.type="aborted",this.code=e??"ABORT_ERR"}};function B(s={}){return kt(e=>{let r=e.shift();if(r==null)return{done:!0};if(r.error!=null)throw r.error;return{done:r.done===!0,value:r.value}},s)}function kt(s,t){t=t??{};let e=t.onEnd,r=new D,n,i,o,a=E(),l=async()=>{try{return r.isEmpty()?o?{done:!0}:await new Promise((c,A)=>{i=N=>{i=null,r.push(N);try{c(s(r))}catch(L){A(L)}return n}}):s(r)}finally{r.isEmpty()&&queueMicrotask(()=>{a.resolve(),a=E()})}},f=c=>i!=null?i(c):(r.push(c),n),b=c=>(r=new D,i!=null?i({error:c}):(r.push({error:c}),n)),d=c=>{if(o)return n;if(t?.objectMode!==!0&&c?.byteLength==null)throw new Error("objectMode was not true but tried to push non-Uint8Array value");return f({done:!1,value:c})},y=c=>o?n:(o=!0,c!=null?b(c):f({done:!0})),T=()=>(r=new D,y(),{done:!0}),Et=c=>(y(c),{done:!0});if(n={[Symbol.asyncIterator](){return this},next:l,return:T,throw:Et,push:d,end:y,get readableLength(){return r.size},onEmpty:async c=>{let A=c?.signal;if(A?.throwIfAborted(),r.isEmpty())return;let N,L;A!=null&&(N=new Promise((Vt,vt)=>{L=()=>{vt(new et)},A.addEventListener("abort",L)}));try{await Promise.race([a.promise,N])}finally{L!=null&&A!=null&&A?.removeEventListener("abort",L)}}},e==null)return n;let C=n;return n={[Symbol.asyncIterator](){return this},next(){return C.next()},throw(c){return C.throw(c),e!=null&&(e(c),e=void 0),{done:!0}},return(){return C.return(),e!=null&&(e(),e=void 0),{done:!0}},push:d,end(c){return C.end(c),e!=null&&(e(c),e=void 0),n},get readableLength(){return C.readableLength},onEmpty:c=>C.onEmpty(c)},n}function x(s=0){return new Uint8Array(s)}function _(s=0){return new Uint8Array(s)}function rt(s,t){t==null&&(t=s.reduce((n,i)=>n+i.length,0));let e=_(t),r=0;for(let n of s)e.set(n,r),r+=n.length;return e}function at(s,t){if(s===t)return!0;if(s.byteLength!==t.byteLength)return!1;for(let e=0;e<s.byteLength;e++)if(s[e]!==t[e])return!1;return!0}var ct=Symbol.for("@achingbrain/uint8arraylist");function lt(s,t){if(t==null||t<0)throw new RangeError("index is out of bounds");let e=0;for(let r of s){let n=e+r.byteLength;if(t<n)return{buf:r,index:t-e};e=n}throw new RangeError("index is out of bounds")}function q(s){return!!s?.[ct]}var v=class s{bufs;length;[ct]=!0;constructor(...t){this.bufs=[],this.length=0,t.length>0&&this.appendAll(t)}*[Symbol.iterator](){yield*this.bufs}get byteLength(){return this.length}append(...t){this.appendAll(t)}appendAll(t){let e=0;for(let r of t)if(r instanceof Uint8Array)e+=r.byteLength,this.bufs.push(r);else if(q(r))e+=r.byteLength,this.bufs.push(...r.bufs);else throw new Error("Could not append value, must be an Uint8Array or a Uint8ArrayList");this.length+=e}prepend(...t){this.prependAll(t)}prependAll(t){let e=0;for(let r of t.reverse())if(r instanceof Uint8Array)e+=r.byteLength,this.bufs.unshift(r);else if(q(r))e+=r.byteLength,this.bufs.unshift(...r.bufs);else throw new Error("Could not prepend value, must be an Uint8Array or a Uint8ArrayList");this.length+=e}get(t){let e=lt(this.bufs,t);return e.buf[e.index]}set(t,e){let r=lt(this.bufs,t);r.buf[r.index]=e}write(t,e=0){if(t instanceof Uint8Array)for(let r=0;r<t.length;r++)this.set(e+r,t[r]);else if(q(t))for(let r=0;r<t.length;r++)this.set(e+r,t.get(r));else throw new Error("Could not write value, must be an Uint8Array or a Uint8ArrayList")}consume(t){if(t=Math.trunc(t),!(Number.isNaN(t)||t<=0)){if(t===this.byteLength){this.bufs=[],this.length=0;return}for(;this.bufs.length>0;)if(t>=this.bufs[0].byteLength)t-=this.bufs[0].byteLength,this.length-=this.bufs[0].byteLength,this.bufs.shift();else{this.bufs[0]=this.bufs[0].subarray(t),this.length-=t;break}}}slice(t,e){let{bufs:r,length:n}=this._subList(t,e);return rt(r,n)}subarray(t,e){let{bufs:r,length:n}=this._subList(t,e);return r.length===1?r[0]:rt(r,n)}sublist(t,e){let{bufs:r,length:n}=this._subList(t,e),i=new s;return i.length=n,i.bufs=[...r],i}_subList(t,e){if(t=t??0,e=e??this.length,t<0&&(t=this.length+t),e<0&&(e=this.length+e),t<0||e>this.length)throw new RangeError("index is out of bounds");if(t===e)return{bufs:[],length:0};if(t===0&&e===this.length)return{bufs:this.bufs,length:this.length};let r=[],n=0;for(let i=0;i<this.bufs.length;i++){let o=this.bufs[i],a=n,l=a+o.byteLength;if(n=l,t>=l)continue;let f=t>=a&&t<l,b=e>a&&e<=l;if(f&&b){if(t===a&&e===l){r.push(o);break}let d=t-a;r.push(o.subarray(d,d+(e-t)));break}if(f){if(t===0){r.push(o);continue}r.push(o.subarray(t-a));continue}if(b){if(e===l){r.push(o);break}r.push(o.subarray(0,e-a));break}r.push(o)}return{bufs:r,length:e-t}}indexOf(t,e=0){if(!q(t)&&!(t instanceof Uint8Array))throw new TypeError('The "value" argument must be a Uint8ArrayList or Uint8Array');let r=t instanceof Uint8Array?t:t.subarray();if(e=Number(e??0),isNaN(e)&&(e=0),e<0&&(e=this.length+e),e<0&&(e=0),t.length===0)return e>this.length?this.length:e;let n=r.byteLength;if(n===0)throw new TypeError("search must be at least 1 byte long");let i=256,o=new Int32Array(i);for(let d=0;d<i;d++)o[d]=-1;for(let d=0;d<n;d++)o[r[d]]=d;let a=o,l=this.byteLength-r.byteLength,f=r.byteLength-1,b;for(let d=e;d<=l;d+=b){b=0;for(let y=f;y>=0;y--){let T=this.get(d+y);if(r[y]!==T){b=Math.max(1,y-a[T]);break}}if(b===0)return d}return-1}getInt8(t){let e=this.subarray(t,t+1);return new DataView(e.buffer,e.byteOffset,e.byteLength).getInt8(0)}setInt8(t,e){let r=_(1);new DataView(r.buffer,r.byteOffset,r.byteLength).setInt8(0,e),this.write(r,t)}getInt16(t,e){let r=this.subarray(t,t+2);return new DataView(r.buffer,r.byteOffset,r.byteLength).getInt16(0,e)}setInt16(t,e,r){let n=x(2);new DataView(n.buffer,n.byteOffset,n.byteLength).setInt16(0,e,r),this.write(n,t)}getInt32(t,e){let r=this.subarray(t,t+4);return new DataView(r.buffer,r.byteOffset,r.byteLength).getInt32(0,e)}setInt32(t,e,r){let n=x(4);new DataView(n.buffer,n.byteOffset,n.byteLength).setInt32(0,e,r),this.write(n,t)}getBigInt64(t,e){let r=this.subarray(t,t+8);return new DataView(r.buffer,r.byteOffset,r.byteLength).getBigInt64(0,e)}setBigInt64(t,e,r){let n=x(8);new DataView(n.buffer,n.byteOffset,n.byteLength).setBigInt64(0,e,r),this.write(n,t)}getUint8(t){let e=this.subarray(t,t+1);return new DataView(e.buffer,e.byteOffset,e.byteLength).getUint8(0)}setUint8(t,e){let r=_(1);new DataView(r.buffer,r.byteOffset,r.byteLength).setUint8(0,e),this.write(r,t)}getUint16(t,e){let r=this.subarray(t,t+2);return new DataView(r.buffer,r.byteOffset,r.byteLength).getUint16(0,e)}setUint16(t,e,r){let n=x(2);new DataView(n.buffer,n.byteOffset,n.byteLength).setUint16(0,e,r),this.write(n,t)}getUint32(t,e){let r=this.subarray(t,t+4);return new DataView(r.buffer,r.byteOffset,r.byteLength).getUint32(0,e)}setUint32(t,e,r){let n=x(4);new DataView(n.buffer,n.byteOffset,n.byteLength).setUint32(0,e,r),this.write(n,t)}getBigUint64(t,e){let r=this.subarray(t,t+8);return new DataView(r.buffer,r.byteOffset,r.byteLength).getBigUint64(0,e)}setBigUint64(t,e,r){let n=x(8);new DataView(n.buffer,n.byteOffset,n.byteLength).setBigUint64(0,e,r),this.write(n,t)}getFloat32(t,e){let r=this.subarray(t,t+4);return new DataView(r.buffer,r.byteOffset,r.byteLength).getFloat32(0,e)}setFloat32(t,e,r){let n=x(4);new DataView(n.buffer,n.byteOffset,n.byteLength).setFloat32(0,e,r),this.write(n,t)}getFloat64(t,e){let r=this.subarray(t,t+8);return new DataView(r.buffer,r.byteOffset,r.byteLength).getFloat64(0,e)}setFloat64(t,e,r){let n=x(8);new DataView(n.buffer,n.byteOffset,n.byteLength).setFloat64(0,e,r),this.write(n,t)}equals(t){if(t==null||!(t instanceof s)||t.bufs.length!==this.bufs.length)return!1;for(let e=0;e<this.bufs.length;e++)if(!at(this.bufs[e],t.bufs[e]))return!1;return!0}static fromUint8Arrays(t,e){let r=new s;return r.bufs=t,e==null&&(e=t.reduce((n,i)=>n+i.byteLength,0)),r.length=e,r}};var w=class extends Error{static name="InvalidFrameError";constructor(t="The frame was invalid"){super(t),this.name="InvalidFrameError"}},W=class extends Error{static name="UnrequestedPingError";constructor(t="Unrequested ping error"){super(t),this.name="UnrequestedPingError"}},k=class extends Error{static name="NotMatchingPingError";constructor(t="Unrequested ping error"){super(t),this.name="NotMatchingPingError"}},Y=class extends Error{static name="InvalidStateError";constructor(t="Invalid state"){super(t),this.name="InvalidStateError"}},H=class extends Error{static name="StreamAlreadyExistsError";constructor(t="Strean already exists"){super(t),this.name="StreamAlreadyExistsError"}},K=class extends Error{static name="DecodeInvalidVersionError";constructor(t="Decode invalid version"){super(t),this.name="DecodeInvalidVersionError"}},$=class extends Error{static name="BothClientsError";constructor(t="Both clients"){super(t),this.name="BothClientsError"}},P=class extends Error{static name="ReceiveWindowExceededError";constructor(t="Receive window exceeded"){super(t),this.name="ReceiveWindowExceededError"}};var ut=new Set([w.name,W.name,k.name,H.name,K.name,$.name,P.name]),U=256*1024,ht=16*1024*1024;var dt={enableKeepAlive:!0,keepAliveInterval:3e4,maxInboundStreams:1e3,maxOutboundStreams:1e3,initialStreamWindowSize:U,maxStreamWindowSize:ht,maxMessageSize:64*1024};function ft(s){if(s.keepAliveInterval<=0)throw new m("keep-alive interval must be positive");if(s.maxInboundStreams<0)throw new m("max inbound streams must be larger or equal 0");if(s.maxOutboundStreams<0)throw new m("max outbound streams must be larger or equal 0");if(s.initialStreamWindowSize<U)throw new m("InitialStreamWindowSize must be larger or equal 256 kB");if(s.maxStreamWindowSize<s.initialStreamWindowSize)throw new m("MaxStreamWindowSize must be larger than the InitialStreamWindowSize");if(s.maxStreamWindowSize>2**32-1)throw new m("MaxStreamWindowSize must be less than equal MAX_UINT32");if(s.maxMessageSize<1024)throw new m("MaxMessageSize must be greater than a kilobyte")}var h;(function(s){s[s.Data=0]="Data",s[s.WindowUpdate=1]="WindowUpdate",s[s.Ping=2]="Ping",s[s.GoAway=3]="GoAway"})(h||(h={}));var u;(function(s){s[s.SYN=1]="SYN",s[s.ACK=2]="ACK",s[s.FIN=4]="FIN",s[s.RST=8]="RST"})(u||(u={}));var Te=Object.values(u).filter(s=>typeof s!="string"),mt=0,p;(function(s){s[s.NormalTermination=0]="NormalTermination",s[s.ProtocolError=1]="ProtocolError",s[s.InternalError=2]="InternalError"})(p||(p={}));var I=12;var pt=2**24;function Pt(s){if(s[0]!==mt)throw new w("Invalid frame version");return{type:s[1],flag:(s[2]<<8)+s[3],streamID:s[4]*pt+(s[5]<<16)+(s[6]<<8)+s[7],length:s[8]*pt+(s[9]<<16)+(s[10]<<8)+s[11]}}var X=class{source;buffer;frameInProgress;constructor(t){this.source=_t(t),this.buffer=new v,this.frameInProgress=!1}async*emitFrames(){for await(let t of this.source)for(this.buffer.append(t);;){let e=this.readHeader();if(e===void 0)break;let{type:r,length:n}=e;r===h.Data?(this.frameInProgress=!0,yield{header:e,readData:this.readBytes.bind(this,n)}):yield{header:e}}}readHeader(){if(this.frameInProgress)throw new Y("decoding frame already in progress");if(this.buffer.length<I)return;let t=Pt(this.buffer.subarray(0,I));return this.buffer.consume(I),t}async readBytes(t){if(this.buffer.length<t){for await(let r of this.source)if(this.buffer.append(r),this.buffer.length>=t)break}let e=this.buffer.sublist(0,t);return this.buffer.consume(t),this.frameInProgress=!1,e}};function _t(s){if(s[Symbol.iterator]!==void 0){let t=s[Symbol.iterator]();return t.return=void 0,{[Symbol.iterator](){return t}}}else if(s[Symbol.asyncIterator]!==void 0){let t=s[Symbol.asyncIterator]();return t.return=void 0,{[Symbol.asyncIterator](){return t}}}else throw new Error("a source must be either an iterable or an async iterable")}function st(s){let t=new Uint8Array(I);return t[1]=s.type,t[2]=s.flag>>>8,t[3]=s.flag,t[4]=s.streamID>>>24,t[5]=s.streamID>>>16,t[6]=s.streamID>>>8,t[7]=s.streamID,t[8]=s.length>>>24,t[9]=s.length>>>16,t[10]=s.length>>>8,t[11]=s.length,t}var j=class extends Error{type;code;constructor(t,e,r){super(t??"The operation was aborted"),this.type="aborted",this.name=r??"AbortError",this.code=e??"ABORT_ERR"}};async function R(s,t,e){if(t==null)return s;if(t.aborted)return s.catch(()=>{}),Promise.reject(new j(e?.errorMessage,e?.errorCode,e?.errorName));let r,n=new j(e?.errorMessage,e?.errorCode,e?.errorName);try{return await Promise.race([s,new Promise((i,o)=>{r=()=>{o(n)},t.addEventListener("abort",r)})])}finally{r!=null&&t.removeEventListener("abort",r)}}function gt(s){return s==null?!1:typeof s.then=="function"&&typeof s.catch=="function"&&typeof s.finally=="function"}function wt(s,t){let e=V(s).return?.();gt(e)&&e.catch(r=>{t.error("could not cause iterator to return",r)})}var Ut=5e3;function nt(s){return s==null?!1:typeof s.then=="function"&&typeof s.catch=="function"&&typeof s.finally=="function"}var J=class{id;direction;timeline;protocol;metadata;source;status;readStatus;writeStatus;log;sinkController;sinkEnd;closed;endErr;streamSource;onEnd;onCloseRead;onCloseWrite;onReset;onAbort;sendCloseWriteTimeout;sendingData;constructor(t){this.sinkController=new AbortController,this.sinkEnd=E(),this.closed=E(),this.log=t.log,this.status="open",this.readStatus="ready",this.writeStatus="ready",this.id=t.id,this.metadata=t.metadata??{},this.direction=t.direction,this.timeline={open:Date.now()},this.sendCloseWriteTimeout=t.sendCloseWriteTimeout??Ut,this.onEnd=t.onEnd,this.onCloseRead=t.onCloseRead,this.onCloseWrite=t.onCloseWrite,this.onReset=t.onReset,this.onAbort=t.onAbort,this.source=this.streamSource=B({onEnd:e=>{e!=null?this.log.trace("source ended with error",e):this.log.trace("source ended"),this.onSourceEnd(e)}}),this.sink=this.sink.bind(this)}async sink(t){if(this.writeStatus!=="ready")throw new F(`writable end state is "${this.writeStatus}" not "ready"`);try{this.writeStatus="writing";let e={signal:this.sinkController.signal};if(this.direction==="outbound"){let n=this.sendNewStream(e);nt(n)&&await n}let r=()=>{wt(t,this.log)};try{this.sinkController.signal.addEventListener("abort",r),this.log.trace("sink reading from source");for await(let n of t){n=n instanceof Uint8Array?new v(n):n;let i=this.sendData(n,e);nt(i)&&(this.sendingData=E(),await i,this.sendingData.resolve(),this.sendingData=void 0)}}finally{this.sinkController.signal.removeEventListener("abort",r)}this.log.trace('sink finished reading from source, write status is "%s"',this.writeStatus),this.writeStatus==="writing"&&(this.writeStatus="closing",this.log.trace("send close write to remote"),await this.sendCloseWrite({signal:AbortSignal.timeout(this.sendCloseWriteTimeout)}),this.writeStatus="closed"),this.onSinkEnd()}catch(e){throw this.log.trace("sink ended with error, calling abort with error",e),this.abort(e),e}finally{this.log.trace("resolve sink end"),this.sinkEnd.resolve()}}onSourceEnd(t){this.timeline.closeRead==null&&(this.timeline.closeRead=Date.now(),this.readStatus="closed",t!=null&&this.endErr==null&&(this.endErr=t),this.onCloseRead?.(),this.timeline.closeWrite!=null?(this.log.trace("source and sink ended"),this.timeline.close=Date.now(),this.status!=="aborted"&&this.status!=="reset"&&(this.status="closed"),this.onEnd!=null&&this.onEnd(this.endErr),this.closed.resolve()):this.log.trace("source ended, waiting for sink to end"))}onSinkEnd(t){this.timeline.closeWrite==null&&(this.timeline.closeWrite=Date.now(),this.writeStatus="closed",t!=null&&this.endErr==null&&(this.endErr=t),this.onCloseWrite?.(),this.timeline.closeRead!=null?(this.log.trace("sink and source ended"),this.timeline.close=Date.now(),this.status!=="aborted"&&this.status!=="reset"&&(this.status="closed"),this.onEnd!=null&&this.onEnd(this.endErr),this.closed.resolve()):this.log.trace("sink ended, waiting for source to end"))}async close(t){this.status==="open"&&(this.log.trace("closing gracefully"),this.status="closing",await R(Promise.all([this.closeWrite(t),this.closeRead(t),this.closed.promise]),t?.signal),this.status="closed",this.log.trace("closed gracefully"))}async closeRead(t={}){if(this.readStatus==="closing"||this.readStatus==="closed")return;this.log.trace('closing readable end of stream with starting read status "%s"',this.readStatus);let e=this.readStatus;this.readStatus="closing",this.status!=="reset"&&this.status!=="aborted"&&this.timeline.closeRead==null&&(this.log.trace("send close read to remote"),await this.sendCloseRead(t)),e==="ready"&&(this.log.trace("ending internal source queue with %d queued bytes",this.streamSource.readableLength),this.streamSource.end()),this.log.trace("closed readable end of stream")}async closeWrite(t={}){this.writeStatus==="closing"||this.writeStatus==="closed"||(this.log.trace('closing writable end of stream with starting write status "%s"',this.writeStatus),this.writeStatus==="ready"&&(this.log.trace("sink was never sunk, sink an empty array"),await R(this.sink([]),t.signal)),this.writeStatus==="writing"&&(this.sendingData!=null&&await R(this.sendingData.promise,t.signal),this.log.trace("aborting source passed to .sink"),this.sinkController.abort(),await R(this.sinkEnd.promise,t.signal)),this.writeStatus="closed",this.log.trace("closed writable end of stream"))}abort(t){if(this.status==="closed"||this.status==="aborted"||this.status==="reset")return;this.log("abort with error",t),this.log("try to send reset to remote");let e=this.sendReset();nt(e)&&e.catch(r=>{this.log.error("error sending reset message",r)}),this.status="aborted",this.timeline.abort=Date.now(),this._closeSinkAndSource(t),this.onAbort?.(t)}reset(){if(this.status==="closed"||this.status==="aborted"||this.status==="reset")return;let t=new O("stream reset");this.status="reset",this.timeline.reset=Date.now(),this._closeSinkAndSource(t),this.onReset?.()}_closeSinkAndSource(t){this._closeSink(t),this._closeSource(t)}_closeSink(t){this.writeStatus==="writing"&&(this.log.trace("end sink source"),this.sinkController.abort()),this.onSinkEnd(t)}_closeSource(t){this.readStatus!=="closing"&&this.readStatus!=="closed"&&(this.log.trace("ending source with %d bytes to be read by consumer",this.streamSource.readableLength),this.readStatus="closing",this.streamSource.end(t))}remoteCloseWrite(){if(this.readStatus==="closing"||this.readStatus==="closed"){this.log("received remote close write but local source is already closed");return}this.log.trace("remote close write"),this._closeSource()}remoteCloseRead(){if(this.writeStatus==="closing"||this.writeStatus==="closed"){this.log("received remote close read but local sink is already closed");return}this.log.trace("remote close read"),this._closeSink()}destroy(){if(this.status==="closed"||this.status==="aborted"||this.status==="reset"){this.log("received destroy but we are already closed");return}this.log.trace("stream destroyed"),this._closeSinkAndSource()}sourcePush(t){this.streamSource.push(t)}sourceReadableLength(){return this.streamSource.readableLength}};function Rt(s){let[t,e]=s[Symbol.asyncIterator]!=null?[s[Symbol.asyncIterator](),Symbol.asyncIterator]:[s[Symbol.iterator](),Symbol.iterator],r=[];return{peek:()=>t.next(),push:n=>{r.push(n)},next:()=>r.length>0?{done:!1,value:r.shift()}:t.next(),[e](){return this}}}var bt=Rt;function Tt(s){return s[Symbol.asyncIterator]!=null}function yt(s){return s?.then!=null}function Nt(s,t){let e=0;if(Tt(s))return async function*(){for await(let l of s){let f=t(l,e++);yt(f)&&await f,yield l}}();let r=bt(s),{value:n,done:i}=r.next();if(i===!0)return function*(){}();if(typeof t(n,e++)?.then=="function")return async function*(){yield n;for(let l of r){let f=t(l,e++);yt(f)&&await f,yield l}}();let a=t;return function*(){yield n;for(let l of r)a(l,e++),yield l}()}var xt=Nt;var g;(function(s){s[s.Init=0]="Init",s[s.SYNSent=1]="SYNSent",s[s.SYNReceived=2]="SYNReceived",s[s.Established=3]="Established",s[s.Finished=4]="Finished"})(g||(g={}));var Q=class extends J{name;state;config;_id;sendWindowCapacity;sendWindowCapacityUpdate;recvWindow;recvWindowCapacity;epochStart;getRTT;sendFrame;constructor(t){super({...t,onEnd:e=>{this.state=g.Finished,t.onEnd?.(e)}}),this.config=t.config,this._id=parseInt(t.id,10),this.name=t.name,this.state=t.state,this.sendWindowCapacity=U,this.recvWindow=this.config.initialStreamWindowSize,this.recvWindowCapacity=this.recvWindow,this.epochStart=Date.now(),this.getRTT=t.getRTT,this.sendFrame=t.sendFrame,this.source=xt(this.source,()=>{this.sendWindowUpdate()})}async sendNewStream(){}async sendData(t,e={}){for(t=t.sublist();t.byteLength!==0;){if(this.sendWindowCapacity===0&&(this.log?.trace("wait for send window capacity, status %s",this.status),await this.waitForSendWindowCapacity(e),this.status==="closed"||this.status==="aborted"||this.status==="reset")){this.log?.trace("%s while waiting for send window capacity",this.status);return}let r=Math.min(this.sendWindowCapacity,this.config.maxMessageSize-I,t.length),n=this.getSendFlags();this.sendFrame({type:h.Data,flag:n,streamID:this._id,length:r},t.sublist(0,r)),this.sendWindowCapacity-=r,t.consume(r)}}async sendReset(){this.sendFrame({type:h.WindowUpdate,flag:u.RST,streamID:this._id,length:0})}async sendCloseWrite(){let t=this.getSendFlags()|u.FIN;this.sendFrame({type:h.WindowUpdate,flag:t,streamID:this._id,length:0})}async sendCloseRead(){}async waitForSendWindowCapacity(t={}){if(this.sendWindowCapacity>0)return;let e,r,n=()=>{this.status==="open"||this.status==="closing"?r(new M("Stream aborted")):e()};t.signal?.addEventListener("abort",n);try{await new Promise((i,o)=>{this.sendWindowCapacityUpdate=()=>{i()},r=o,e=i})}finally{t.signal?.removeEventListener("abort",n)}}handleWindowUpdate(t){this.log?.trace("stream received window update id=%s",this._id),this.processFlags(t.flag);let e=this.sendWindowCapacity;this.sendWindowCapacity+=t.length,e===0&&t.length>0&&this.sendWindowCapacityUpdate?.()}async handleData(t,e){if(this.log?.trace("stream received data id=%s",this._id),this.processFlags(t.flag),this.recvWindowCapacity<t.length)throw new P("Receive window exceeded");let r=await e();this.recvWindowCapacity-=t.length,this.sourcePush(r)}processFlags(t){(t&u.ACK)===u.ACK&&this.state===g.SYNSent&&(this.state=g.Established),(t&u.FIN)===u.FIN&&this.remoteCloseWrite(),(t&u.RST)===u.RST&&this.reset()}getSendFlags(){switch(this.state){case g.Init:return this.state=g.SYNSent,u.SYN;case g.SYNReceived:return this.state=g.Established,u.ACK;default:return 0}}sendWindowUpdate(){let t=this.getSendFlags(),e=Date.now(),r=this.getRTT();if(t===0&&r>-1&&e-this.epochStart<r*4&&(this.recvWindow=Math.min(this.recvWindow*2,this.config.maxStreamWindowSize)),this.recvWindowCapacity>=this.recvWindow&&t===0)return;let n=this.recvWindow-this.recvWindowCapacity;this.recvWindowCapacity=this.recvWindow,this.epochStart=e,this.sendFrame({type:h.WindowUpdate,flag:t,streamID:this._id,length:n})}};var St="/yamux/1.0.0",Mt=500,Z=class{protocol=St;_components;_init;constructor(t,e={}){this._components=t,this._init=e}[Symbol.toStringTag]="@chainsafe/libp2p-yamux";[ot]=["@libp2p/stream-multiplexing"];createStreamMuxer(t){return new it(this._components,{...this._init,...t})}},it=class{protocol=St;source;sink;config;log;logger;closeController;nextStreamID;_streams;nextPingID;activePing;rtt;client;localGoAway;remoteGoAway;numInboundStreams;numOutboundStreams;onIncomingStream;onStreamEnd;constructor(t,e){this.client=e.direction==="outbound",this.config={...dt,...e},this.logger=t.logger,this.log=this.logger.forComponent("libp2p:yamux"),ft(this.config),this.closeController=new AbortController,this.closeController.signal,this.onIncomingStream=e.onIncomingStream,this.onStreamEnd=e.onStreamEnd,this._streams=new Map,this.source=B({onEnd:()=>{this.log?.trace("muxer source ended"),this._streams.forEach(r=>{r.destroy()})}}),this.sink=async r=>{let n=()=>{let a=V(r);if(a.return!=null){let l=a.return();Ot(l)&&l.catch(f=>{this.log?.("could not cause sink source to return",f)})}},i,o;try{let a=new X(r);try{this.closeController.signal.addEventListener("abort",n);for await(let l of a.emitFrames())await this.handleFrame(l.header,l.readData)}finally{this.closeController.signal.removeEventListener("abort",n)}i=p.NormalTermination}catch(a){ut.has(a.name)?(this.log?.error("protocol error in sink",a),i=p.ProtocolError):(this.log?.error("internal error in sink",a),i=p.InternalError),o=a}this.log?.trace("muxer sink ended"),o!=null?this.abort(o,i):await this.close({reason:i})},this.numInboundStreams=0,this.numOutboundStreams=0,this.nextStreamID=this.client?1:2,this.nextPingID=0,this.rtt=-1,this.log?.trace("muxer created"),this.config.enableKeepAlive&&this.keepAliveLoop().catch(r=>this.log?.error("keepalive error: %s",r)),this.ping().catch(r=>this.log?.error("ping error: %s",r))}get streams(){return Array.from(this._streams.values())}newStream(t){if(this.remoteGoAway!==void 0)throw new S("Muxer closed remotely");if(this.localGoAway!==void 0)throw new S("Muxer closed locally");let e=this.nextStreamID;if(this.nextStreamID+=2,this.numOutboundStreams>=this.config.maxOutboundStreams)throw new z("max outbound streams exceeded");this.log?.trace("new outgoing stream id=%s",e);let r=this._newStream(e,t,g.Init,"outbound");return this._streams.set(e,r),this.numOutboundStreams++,r.sendWindowUpdate(),r}async ping(){if(this.remoteGoAway!==void 0)throw new S("Muxer closed remotely");if(this.localGoAway!==void 0)throw new S("Muxer closed locally");if(this.activePing===void 0){let t=()=>{};this.activePing={id:this.nextPingID++,promise:new Promise((n,i)=>{let o=()=>{i(new S("Muxer closed locally"))};this.closeController.signal.addEventListener("abort",o,{once:!0}),t=()=>{this.closeController.signal.removeEventListener("abort",o),n()}}),resolve:t};let e=Date.now();this.sendPing(this.activePing.id);try{await this.activePing.promise}finally{delete this.activePing}let r=Date.now();this.rtt=r-e}else await this.activePing.promise;return this.rtt}getRTT(){return this.rtt}async close(t={}){if(this.closeController.signal.aborted)return;let e=t?.reason??p.NormalTermination;if(this.log?.trace("muxer close reason=%s",e),t.signal==null){let r=AbortSignal.timeout(Mt);t={...t,signal:r}}try{await Promise.all([...this._streams.values()].map(async r=>r.close(t))),this.sendGoAway(e),this._closeMuxer()}catch(r){this.abort(r)}}abort(t,e){if(!this.closeController.signal.aborted){e=e??p.InternalError,this.log?.error("muxer abort reason=%s error=%s",e,t);for(let r of this._streams.values())r.abort(t);this.sendGoAway(e),this._closeMuxer()}}isClosed(){return this.closeController.signal.aborted}_closeMuxer(){this.closeController.abort(),this.source.end()}_newStream(t,e,r,n){if(this._streams.get(t)!=null)throw new m("Stream already exists with that id");let i=new Q({id:t.toString(),name:e,state:r,direction:n,sendFrame:this.sendFrame.bind(this),onEnd:()=>{this.closeStream(t),this.onStreamEnd?.(i)},log:this.logger.forComponent(`libp2p:yamux:${n}:${t}`),config:this.config,getRTT:this.getRTT.bind(this)});return i}closeStream(t){this.client===(t%2===0)?this.numInboundStreams--:this.numOutboundStreams--,this._streams.delete(t)}async keepAliveLoop(){let t=new Promise((e,r)=>{this.closeController.signal.addEventListener("abort",r,{once:!0})});for(this.log?.trace("muxer keepalive enabled interval=%s",this.config.keepAliveInterval);;){let e;try{await Promise.race([t,new Promise(r=>{e=setTimeout(r,this.config.keepAliveInterval)})]),this.ping().catch(r=>this.log?.error("ping error: %s",r))}catch{clearInterval(e);return}}}async handleFrame(t,e){let{streamID:r,type:n,length:i}=t;if(this.log?.trace("received frame %o",t),r===0)switch(n){case h.Ping:{this.handlePing(t);return}case h.GoAway:{this.handleGoAway(i);return}default:throw new w("Invalid frame type")}else switch(t.type){case h.Data:case h.WindowUpdate:{await this.handleStreamMessage(t,e);return}default:throw new w("Invalid frame type")}}handlePing(t){if(t.flag===u.SYN)this.log?.trace("received ping request pingId=%s",t.length),this.sendPing(t.length,u.ACK);else if(t.flag===u.ACK)this.log?.trace("received ping response pingId=%s",t.length),this.handlePingResponse(t.length);else throw new w("Invalid frame flag")}handlePingResponse(t){if(this.activePing===void 0)throw new W("ping not requested");if(this.activePing.id!==t)throw new k("ping doesn't match our id");this.activePing.resolve()}handleGoAway(t){this.log?.trace("received GoAway reason=%s",p[t]??"unknown"),this.remoteGoAway=t;for(let e of this._streams.values())e.reset();this._closeMuxer()}async handleStreamMessage(t,e){let{streamID:r,flag:n,type:i}=t;(n&u.SYN)===u.SYN&&this.incomingStream(r);let o=this._streams.get(r);if(o===void 0){if(i===h.Data){if(this.log?.("discarding data for stream id=%s",r),e===void 0)throw new Error("unreachable");await e()}else this.log?.trace("frame for missing stream id=%s",r);return}switch(i){case h.WindowUpdate:{o.handleWindowUpdate(t);return}case h.Data:{if(e===void 0)throw new Error("unreachable");await o.handleData(t,e);return}default:throw new Error("unreachable")}}incomingStream(t){if(this.client!==(t%2===0))throw new m("Both endpoints are clients");if(this._streams.has(t))return;if(this.log?.trace("new incoming stream id=%s",t),this.localGoAway!==void 0){this.sendFrame({type:h.WindowUpdate,flag:u.RST,streamID:t,length:0});return}if(this.numInboundStreams>=this.config.maxInboundStreams){this.log?.("maxIncomingStreams exceeded, forcing stream reset"),this.sendFrame({type:h.WindowUpdate,flag:u.RST,streamID:t,length:0});return}let e=this._newStream(t,void 0,g.SYNReceived,"inbound");this.numInboundStreams++,this._streams.set(t,e),this.onIncomingStream?.(e)}sendFrame(t,e){if(this.log?.trace("sending frame %o",t),t.type===h.Data){if(e===void 0)throw new w("Invalid frame");this.source.push(new v(st(t),e))}else this.source.push(st(t))}sendPing(t,e=u.SYN){e===u.SYN?this.log?.trace("sending ping request pingId=%s",t):this.log?.trace("sending ping response pingId=%s",t),this.sendFrame({type:h.Ping,flag:e,streamID:0,length:t})}sendGoAway(t=p.NormalTermination){this.log?.("sending GoAway reason=%s",p[t]),this.localGoAway=t,this.sendFrame({type:h.GoAway,flag:0,streamID:0,length:t})}};function Ot(s){return s!=null&&typeof s.then=="function"}function Ft(s={}){return t=>new Z(t,s)}return Wt(zt);})(); return ChainsafeLibp2PYamux})); //# sourceMappingURL=index.min.js.map