@libp2p/perf 4.0.46-cf9aab5c8 → 4.0.47-a02cb0461

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.min.js CHANGED
@@ -1,4 +1,4 @@
1
1
  (function (root, factory) {(typeof module === 'object' && module.exports) ? module.exports = factory() : root.Libp2PPerf = factory()}(typeof self !== 'undefined' ? self : this, function () {
2
- "use strict";var Libp2PPerf=(()=>{var D=Object.defineProperty;var T=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames;var v=Object.prototype.hasOwnProperty;var k=(i,t)=>{for(var e in t)D(i,e,{get:t[e],enumerable:!0})},A=(i,t,e,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of M(t))!v.call(i,r)&&r!==e&&D(i,r,{get:()=>t[r],enumerable:!(o=T(t,r))||o.enumerable});return i};var z=i=>A(D({},"__esModule",{value:!0}),i);var K={};k(K,{perf:()=>j});function g(){let i={};return i.promise=new Promise((t,e)=>{i.resolve=t,i.reject=e}),i}var E=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}},y=class{size;hwm;head;tail;constructor(t={}){this.hwm=t.splitLimit??16,this.head=new E(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 E(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 N=class extends Error{type;code;constructor(t,e){super(t??"The operation was aborted"),this.type="aborted",this.code=e??"ABORT_ERR"}};function _(i={}){return C(e=>{let o=e.shift();if(o==null)return{done:!0};if(o.error!=null)throw o.error;return{done:o.done===!0,value:o.value}},i)}function C(i,t){t=t??{};let e=t.onEnd,o=new y,r,l,s,S=g(),a=async()=>{try{return o.isEmpty()?s?{done:!0}:await new Promise((n,h)=>{l=d=>{l=null,o.push(d);try{n(i(o))}catch(p){h(p)}return r}}):i(o)}finally{o.isEmpty()&&queueMicrotask(()=>{S.resolve(),S=g()})}},f=n=>l!=null?l(n):(o.push(n),r),c=n=>(o=new y,l!=null?l({error:n}):(o.push({error:n}),r)),m=n=>{if(s)return r;if(t?.objectMode!==!0&&n?.byteLength==null)throw new Error("objectMode was not true but tried to push non-Uint8Array value");return f({done:!1,value:n})},w=n=>s?r:(s=!0,n!=null?c(n):f({done:!0})),x=()=>(o=new y,w(),{done:!0}),B=n=>(w(n),{done:!0});if(r={[Symbol.asyncIterator](){return this},next:a,return:x,throw:B,push:m,end:w,get readableLength(){return o.size},onEmpty:async n=>{let h=n?.signal;if(h?.throwIfAborted(),o.isEmpty())return;let d,p;h!=null&&(d=new Promise((u,I)=>{p=()=>{I(new N)},h.addEventListener("abort",p)}));try{await Promise.race([S.promise,d])}finally{p!=null&&h!=null&&h?.removeEventListener("abort",p)}}},e==null)return r;let b=r;return r={[Symbol.asyncIterator](){return this},next(){return b.next()},throw(n){return b.throw(n),e!=null&&(e(n),e=void 0),{done:!0}},return(){return b.return(),e!=null&&(e(),e=void 0),{done:!0}},push:m,end(n){return b.end(n),e!=null&&(e(n),e=void 0),r},get readableLength(){return b.readableLength},onEmpty:n=>b.onEmpty(n)},r}var L="/perf/1.0.0";var O=class{log;protocol;components;started;buf;writeBlockSize;maxInboundStreams;maxOutboundStreams;runOnLimitedConnection;constructor(t,e={}){this.components=t,this.log=t.logger.forComponent("libp2p:perf"),this.started=!1,this.protocol=e.protocolName??L,this.writeBlockSize=e.writeBlockSize??65536,this.buf=new ArrayBuffer(this.writeBlockSize),this.maxInboundStreams=e.maxInboundStreams??1,this.maxOutboundStreams=e.maxOutboundStreams??1,this.runOnLimitedConnection=e.runOnLimitedConnection??!1}[Symbol.toStringTag]="@libp2p/perf";async start(){await this.components.registrar.handle(this.protocol,t=>{this.handleMessage(t).catch(e=>{this.log.error("error handling perf protocol message - %e",e)})},{maxInboundStreams:this.maxInboundStreams,maxOutboundStreams:this.maxOutboundStreams,runOnLimitedConnection:this.runOnLimitedConnection}),this.started=!0}async stop(){await this.components.registrar.unhandle(this.protocol),this.started=!1}isStarted(){return this.started}async handleMessage(t){let{stream:e}=t;try{let o=this.writeBlockSize,r;for await(let s of e.source)r==null&&(r=Number(s.getBigUint64(0,!1)));if(r==null)throw new Error("bytesToSendBack was not set");let l=new Uint8Array(this.buf,0,this.buf.byteLength);await e.sink(async function*(){for(;r>0;){let s=o;s>r&&(s=r),r=r-s,yield l.subarray(0,s)}}())}catch(o){e.abort(o)}}async*measurePerformance(t,e,o,r={}){let l=new Uint8Array(this.buf),s=this.writeBlockSize,S=Date.now(),a=Date.now(),f=await this.components.connectionManager.openConnection(t,{...r,force:r.reuseExistingConnection!==!0}),c=f.log.newScope("perf");c("opened connection after %d ms",Date.now()-a),a=Date.now();let m=await f.newStream(this.protocol,r);c("opened stream after %d ms",Date.now()-a),a=Date.now();let w=0,x=0,B=Date.now();new DataView(this.buf).setBigUint64(0,BigInt(o),!1),c("sending %i bytes to %p",e,f.remotePeer);try{let n=_({objectMode:!0});m.sink(async function*(){for(yield l.subarray(0,8);e>0;){let u=s;u>e&&(u=e),yield l.subarray(0,u),e-=u,Date.now()-a>1e3&&(n.push({type:"intermediary",timeSeconds:(Date.now()-a)/1e3,uploadBytes:w,downloadBytes:0}),a=Date.now(),w=0),w+=u,x+=u}n.end()}()).catch(u=>{n.end(u)}),yield*n,c("upload complete after %d ms",Date.now()-B);let h=0;a=Date.now();let d=0,p=Date.now();for await(let u of m.source)Date.now()-a>1e3&&(yield{type:"intermediary",timeSeconds:(Date.now()-a)/1e3,uploadBytes:0,downloadBytes:h},a=Date.now(),h=0),h+=u.byteLength,d+=u.byteLength;if(c("download complete after %d ms",Date.now()-p),d!==o)throw new Error(`Expected to receive ${o} bytes, but received ${d}`);yield{type:"final",timeSeconds:(Date.now()-S)/1e3,uploadBytes:x,downloadBytes:d},c("performed %s to %p",this.protocol,f.remotePeer),await m.close()}catch(n){throw c("error sending %d/%d bytes to %p: %s",x,e,f.remotePeer,n),m.abort(n),n}}};function j(i={}){return t=>new O(t,i)}return z(K);})();
2
+ "use strict";var Libp2PPerf=(()=>{var N=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var X=Object.getOwnPropertyNames;var Y=Object.prototype.hasOwnProperty;var $=(s,t)=>{for(var e in t)N(s,e,{get:t[e],enumerable:!0})},K=(s,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of X(t))!Y.call(s,r)&&r!==e&&N(s,r,{get:()=>t[r],enumerable:!(n=q(t,r))||n.enumerable});return s};var Q=s=>K(N({},"__esModule",{value:!0}),s);var st={};$(st,{perf:()=>rt});function I(){let s={};return s.promise=new Promise((t,e)=>{s.resolve=t,s.reject=e}),s}var A=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}},x=class{size;hwm;head;tail;constructor(t={}){this.hwm=t.splitLimit??16,this.head=new A(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 A(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 B=class extends Error{type;code;constructor(t,e){super(t??"The operation was aborted"),this.type="aborted",this.code=e??"ABORT_ERR"}};function k(s={}){return W(e=>{let n=e.shift();if(n==null)return{done:!0};if(n.error!=null)throw n.error;return{done:n.done===!0,value:n.value}},s)}function W(s,t){t=t??{};let e=t.onEnd,n=new x,r,i,f,c=I(),l=async()=>{try{return n.isEmpty()?f?{done:!0}:await new Promise((a,w)=>{i=m=>{i=null,n.push(m);try{a(s(n))}catch(y){w(y)}return r}}):s(n)}finally{n.isEmpty()&&queueMicrotask(()=>{c.resolve(),c=I()})}},b=a=>i!=null?i(a):(n.push(a),r),h=a=>(n=new x,i!=null?i({error:a}):(n.push({error:a}),r)),o=a=>{if(f)return r;if(t?.objectMode!==!0&&a?.byteLength==null)throw new Error("objectMode was not true but tried to push non-Uint8Array value");return b({done:!1,value:a})},d=a=>f?r:(f=!0,a!=null?h(a):b({done:!0})),u=()=>(n=new x,d(),{done:!0}),L=a=>(d(a),{done:!0});if(r={[Symbol.asyncIterator](){return this},next:l,return:u,throw:L,push:o,end:d,get readableLength(){return n.size},onEmpty:async a=>{let w=a?.signal;if(w?.throwIfAborted(),n.isEmpty())return;let m,y;w!=null&&(m=new Promise((E,p)=>{y=()=>{p(new B)},w.addEventListener("abort",y)}));try{await Promise.race([c.promise,m])}finally{y!=null&&w!=null&&w?.removeEventListener("abort",y)}}},e==null)return r;let v=r;return r={[Symbol.asyncIterator](){return this},next(){return v.next()},throw(a){return v.throw(a),e!=null&&(e(a),e=void 0),{done:!0}},return(){return v.return(),e!=null&&(e(),e=void 0),{done:!0}},push:o,end(a){return v.end(a),e!=null&&(e(a),e=void 0),r},get readableLength(){return v.readableLength},onEmpty:a=>v.onEmpty(a)},r}var M=class extends Error{constructor(t){super(t),this.name="TimeoutError"}},V=class extends Error{constructor(t){super(),this.name="AbortError",this.message=t}},C=s=>globalThis.DOMException===void 0?new V(s):new DOMException(s),R=s=>{let t=s.reason===void 0?C("This operation was aborted."):s.reason;return t instanceof Error?t:C(t)};function P(s,t){let{milliseconds:e,fallback:n,message:r,customTimers:i={setTimeout,clearTimeout}}=t,f,c,b=new Promise((h,o)=>{if(typeof e!="number"||Math.sign(e)!==1)throw new TypeError(`Expected \`milliseconds\` to be a positive number, got \`${e}\``);if(t.signal){let{signal:u}=t;u.aborted&&o(R(u)),c=()=>{o(R(u))},u.addEventListener("abort",c,{once:!0})}if(e===Number.POSITIVE_INFINITY){s.then(h,o);return}let d=new M;f=i.setTimeout.call(void 0,()=>{if(n){try{h(n())}catch(u){o(u)}return}typeof s.cancel=="function"&&s.cancel(),r===!1?h():r instanceof Error?o(r):(d.message=r??`Promise timed out after ${e} milliseconds`,o(d))},e),(async()=>{try{h(await s)}catch(u){o(u)}})()}).finally(()=>{b.clear(),c&&t.signal&&t.signal.removeEventListener("abort",c)});return b.clear=()=>{i.clearTimeout.call(void 0,f),f=void 0},b}var Z=s=>{let t=s.addEventListener||s.on||s.addListener,e=s.removeEventListener||s.off||s.removeListener;if(!t||!e)throw new TypeError("Emitter is not compatible");return{addListener:t.bind(s),removeListener:e.bind(s)}};function G(s,t,e){let n,r=new Promise((i,f)=>{if(e={rejectionEvents:["error"],multiArgs:!1,resolveImmediately:!1,...e},!(e.count>=0&&(e.count===Number.POSITIVE_INFINITY||Number.isInteger(e.count))))throw new TypeError("The `count` option should be at least 0 or more");e.signal?.throwIfAborted();let c=[t].flat(),l=[],{addListener:b,removeListener:h}=Z(s),o=(...u)=>{let L=e.multiArgs?u:u[0];e.filter&&!e.filter(L)||(l.push(L),e.count===l.length&&(n(),i(l)))},d=u=>{n(),f(u)};n=()=>{for(let u of c)h(u,o);for(let u of e.rejectionEvents)h(u,d)};for(let u of c)b(u,o);for(let u of e.rejectionEvents)b(u,d);e.signal&&e.signal.addEventListener("abort",()=>{d(e.signal.reason)},{once:!0}),e.resolveImmediately&&i(l)});if(r.cancel=n,typeof e.timeout=="number"){let i=P(r,{milliseconds:e.timeout});return i.cancel=n,i}return r}function O(s,t,e){typeof e=="function"&&(e={filter:e}),e={...e,count:1,resolveImmediately:!1};let n=G(s,t,e),r=n.then(i=>i[0]);return r.cancel=n.cancel,r}function g(s=0){return new Uint8Array(s)}function S(s=0){return new Uint8Array(s)}function _(s,t){t==null&&(t=s.reduce((r,i)=>r+i.length,0));let e=S(t),n=0;for(let r of s)e.set(r,n),n+=r.length;return e}function z(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 F=Symbol.for("@achingbrain/uint8arraylist");function j(s,t){if(t==null||t<0)throw new RangeError("index is out of bounds");let e=0;for(let n of s){let r=e+n.byteLength;if(t<r)return{buf:n,index:t-e};e=r}throw new RangeError("index is out of bounds")}function U(s){return!!s?.[F]}var D=class s{bufs;length;[F]=!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 n of t)if(n instanceof Uint8Array)e+=n.byteLength,this.bufs.push(n);else if(U(n))e+=n.byteLength,this.bufs.push(...n.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 n of t.reverse())if(n instanceof Uint8Array)e+=n.byteLength,this.bufs.unshift(n);else if(U(n))e+=n.byteLength,this.bufs.unshift(...n.bufs);else throw new Error("Could not prepend value, must be an Uint8Array or a Uint8ArrayList");this.length+=e}get(t){let e=j(this.bufs,t);return e.buf[e.index]}set(t,e){let n=j(this.bufs,t);n.buf[n.index]=e}write(t,e=0){if(t instanceof Uint8Array)for(let n=0;n<t.length;n++)this.set(e+n,t[n]);else if(U(t))for(let n=0;n<t.length;n++)this.set(e+n,t.get(n));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:n,length:r}=this._subList(t,e);return _(n,r)}subarray(t,e){let{bufs:n,length:r}=this._subList(t,e);return n.length===1?n[0]:_(n,r)}sublist(t,e){let{bufs:n,length:r}=this._subList(t,e),i=new s;return i.length=r,i.bufs=[...n],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 n=[],r=0;for(let i=0;i<this.bufs.length;i++){let f=this.bufs[i],c=r,l=c+f.byteLength;if(r=l,t>=l)continue;let b=t>=c&&t<l,h=e>c&&e<=l;if(b&&h){if(t===c&&e===l){n.push(f);break}let o=t-c;n.push(f.subarray(o,o+(e-t)));break}if(b){if(t===0){n.push(f);continue}n.push(f.subarray(t-c));continue}if(h){if(e===l){n.push(f);break}n.push(f.subarray(0,e-c));break}n.push(f)}return{bufs:n,length:e-t}}indexOf(t,e=0){if(!U(t)&&!(t instanceof Uint8Array))throw new TypeError('The "value" argument must be a Uint8ArrayList or Uint8Array');let n=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 r=n.byteLength;if(r===0)throw new TypeError("search must be at least 1 byte long");let i=256,f=new Int32Array(i);for(let o=0;o<i;o++)f[o]=-1;for(let o=0;o<r;o++)f[n[o]]=o;let c=f,l=this.byteLength-n.byteLength,b=n.byteLength-1,h;for(let o=e;o<=l;o+=h){h=0;for(let d=b;d>=0;d--){let u=this.get(o+d);if(n[d]!==u){h=Math.max(1,d-c[u]);break}}if(h===0)return o}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 n=S(1);new DataView(n.buffer,n.byteOffset,n.byteLength).setInt8(0,e),this.write(n,t)}getInt16(t,e){let n=this.subarray(t,t+2);return new DataView(n.buffer,n.byteOffset,n.byteLength).getInt16(0,e)}setInt16(t,e,n){let r=g(2);new DataView(r.buffer,r.byteOffset,r.byteLength).setInt16(0,e,n),this.write(r,t)}getInt32(t,e){let n=this.subarray(t,t+4);return new DataView(n.buffer,n.byteOffset,n.byteLength).getInt32(0,e)}setInt32(t,e,n){let r=g(4);new DataView(r.buffer,r.byteOffset,r.byteLength).setInt32(0,e,n),this.write(r,t)}getBigInt64(t,e){let n=this.subarray(t,t+8);return new DataView(n.buffer,n.byteOffset,n.byteLength).getBigInt64(0,e)}setBigInt64(t,e,n){let r=g(8);new DataView(r.buffer,r.byteOffset,r.byteLength).setBigInt64(0,e,n),this.write(r,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 n=S(1);new DataView(n.buffer,n.byteOffset,n.byteLength).setUint8(0,e),this.write(n,t)}getUint16(t,e){let n=this.subarray(t,t+2);return new DataView(n.buffer,n.byteOffset,n.byteLength).getUint16(0,e)}setUint16(t,e,n){let r=g(2);new DataView(r.buffer,r.byteOffset,r.byteLength).setUint16(0,e,n),this.write(r,t)}getUint32(t,e){let n=this.subarray(t,t+4);return new DataView(n.buffer,n.byteOffset,n.byteLength).getUint32(0,e)}setUint32(t,e,n){let r=g(4);new DataView(r.buffer,r.byteOffset,r.byteLength).setUint32(0,e,n),this.write(r,t)}getBigUint64(t,e){let n=this.subarray(t,t+8);return new DataView(n.buffer,n.byteOffset,n.byteLength).getBigUint64(0,e)}setBigUint64(t,e,n){let r=g(8);new DataView(r.buffer,r.byteOffset,r.byteLength).setBigUint64(0,e,n),this.write(r,t)}getFloat32(t,e){let n=this.subarray(t,t+4);return new DataView(n.buffer,n.byteOffset,n.byteLength).getFloat32(0,e)}setFloat32(t,e,n){let r=g(4);new DataView(r.buffer,r.byteOffset,r.byteLength).setFloat32(0,e,n),this.write(r,t)}getFloat64(t,e){let n=this.subarray(t,t+8);return new DataView(n.buffer,n.byteOffset,n.byteLength).getFloat64(0,e)}setFloat64(t,e,n){let r=g(8);new DataView(r.buffer,r.byteOffset,r.byteLength).setFloat64(0,e,n),this.write(r,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(!z(this.bufs[e],t.bufs[e]))return!1;return!0}static fromUint8Arrays(t,e){let n=new s;return n.bufs=t,e==null&&(e=t.reduce((r,i)=>r+i.byteLength,0)),n.length=e,n}};var H="/perf/1.0.0";var T=class{log;protocol;components;started;buf;writeBlockSize;maxInboundStreams;maxOutboundStreams;runOnLimitedConnection;constructor(t,e={}){this.components=t,this.log=t.logger.forComponent("libp2p:perf"),this.started=!1,this.protocol=e.protocolName??H,this.writeBlockSize=e.writeBlockSize??65536,this.buf=new ArrayBuffer(this.writeBlockSize),this.maxInboundStreams=e.maxInboundStreams??1,this.maxOutboundStreams=e.maxOutboundStreams??1,this.runOnLimitedConnection=e.runOnLimitedConnection??!1,this.handleMessage=this.handleMessage.bind(this)}[Symbol.toStringTag]="@libp2p/perf";async start(){await this.components.registrar.handle(this.protocol,this.handleMessage,{maxInboundStreams:this.maxInboundStreams,maxOutboundStreams:this.maxOutboundStreams,runOnLimitedConnection:this.runOnLimitedConnection}),this.started=!0}async stop(){await this.components.registrar.unhandle(this.protocol),this.started=!1}isStarted(){return this.started}async handleMessage(t){try{let e=this.writeBlockSize,n;for await(let i of t)if(n==null){let f=new D(i);n=Number(f.getBigUint64(0,!1))}if(n==null)throw new Error("bytesToSendBack was not set");let r=new Uint8Array(this.buf,0,this.buf.byteLength);for(;n>0;){let i=e;i>n&&(i=n),n=n-i;let f=r.subarray(0,i);t.send(f)||await O(t,"drain",{rejectionEvents:["close"]})}await t.close()}catch(e){t.abort(e)}}async*measurePerformance(t,e,n,r={}){let i=new Uint8Array(this.buf),f=this.writeBlockSize,c=Date.now(),l=Date.now(),b=await this.components.connectionManager.openConnection(t,{...r,force:r.reuseExistingConnection!==!0}),h=b.log.newScope("perf");h("opened connection after %d ms",Date.now()-l),l=Date.now();let o=await b.newStream(this.protocol,r);h("opened stream after %d ms",Date.now()-l),l=Date.now();let d=0,u=0,L=Date.now();new DataView(this.buf).setBigUint64(0,BigInt(n),!1),h("sending %i bytes to %p",e,b.remotePeer);try{let a=k({objectMode:!0});Promise.resolve().then(async()=>{for(o.send(i.subarray(0,8))||await O(o,"drain",{rejectionEvents:["close"],signal:r.signal});e>0;){let p=f;p>e&&(p=e),o.send(i.subarray(0,p))||await O(o,"drain",{rejectionEvents:["close"],signal:r.signal}),e-=p,Date.now()-l>1e3&&(a.push({type:"intermediary",timeSeconds:(Date.now()-l)/1e3,uploadBytes:d,downloadBytes:0}),l=Date.now(),d=0),d+=p,u+=p}a.end()}).catch(E=>{a.end(E)}),yield*a,h("upload complete after %d ms",Date.now()-L),await o.close(r);let w=0;l=Date.now();let m=0,y=Date.now();for await(let E of o)Date.now()-l>1e3&&(yield{type:"intermediary",timeSeconds:(Date.now()-l)/1e3,uploadBytes:0,downloadBytes:w},l=Date.now(),w=0),w+=E.byteLength,m+=E.byteLength;if(h("download complete after %d ms",Date.now()-y),m!==n)throw new Error(`Expected to receive ${n} bytes, but received ${m}`);yield{type:"final",timeSeconds:(Date.now()-c)/1e3,uploadBytes:u,downloadBytes:m},h("performed %s to %p",this.protocol,b.remotePeer)}catch(a){throw h("error sending %d/%d bytes to %p: %s",u,e,b.remotePeer,a),o.abort(a),a}}};function rt(s={}){return t=>new T(t,s)}return Q(st);})();
3
3
  return Libp2PPerf}));
4
4
  //# sourceMappingURL=index.min.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/index.ts", "../../../node_modules/p-defer/index.js", "../../../node_modules/it-pushable/src/fifo.ts", "../../../node_modules/it-pushable/src/index.ts", "../src/constants.ts", "../src/perf-service.ts"],
4
- "sourcesContent": ["/**\n * @packageDocumentation\n *\n * The {@link Perf} service implements the [perf protocol](https://github.com/libp2p/specs/blob/master/perf/perf.md), which can be used to measure transfer performance within and across libp2p implementations.\n *\n * @example\n *\n * ```typescript\n * import { noise } from '@chainsafe/libp2p-noise'\n * import { yamux } from '@chainsafe/libp2p-yamux'\n * import { tcp } from '@libp2p/tcp'\n * import { createLibp2p, type Libp2p } from 'libp2p'\n * import { plaintext } from '@libp2p/plaintext'\n * import { perf, type Perf } from '@libp2p/perf'\n *\n * const ONE_MEG = 1024 * 1024\n * const UPLOAD_BYTES = ONE_MEG * 1024\n * const DOWNLOAD_BYTES = ONE_MEG * 1024\n *\n * async function createNode (): Promise<Libp2p<{ perf: Perf }>> {\n * return createLibp2p({\n * addresses: {\n * listen: [\n * '/ip4/0.0.0.0/tcp/0'\n * ]\n * },\n * transports: [\n * tcp()\n * ],\n * connectionEncrypters: [\n * noise(), plaintext()\n * ],\n * streamMuxers: [\n * yamux()\n * ],\n * services: {\n * perf: perf()\n * }\n * })\n * }\n *\n * const libp2p1 = await createNode()\n * const libp2p2 = await createNode()\n *\n * for await (const output of libp2p1.services.perf.measurePerformance(libp2p2.getMultiaddrs()[0], UPLOAD_BYTES, DOWNLOAD_BYTES)) {\n * console.info(output)\n * }\n *\n * await libp2p1.stop()\n * await libp2p2.stop()\n * ```\n */\n\nimport { Perf as PerfClass } from './perf-service.js'\nimport type { AbortOptions, ComponentLogger } from '@libp2p/interface'\nimport type { ConnectionManager, Registrar } from '@libp2p/interface-internal'\nimport type { Multiaddr } from '@multiformats/multiaddr'\n\nexport interface PerfOptions extends AbortOptions {\n /**\n * By default measuring perf should include the time it takes to establish a\n * connection, so a new connection will be opened for every performance run.\n *\n * To override this and re-use an existing connection if one is present, pass\n * `true` here.\n *\n * @default false\n */\n reuseExistingConnection?: boolean\n}\n\nexport interface Perf {\n measurePerformance(multiaddr: Multiaddr, sendBytes: number, recvBytes: number, options?: PerfOptions): AsyncGenerator<PerfOutput>\n}\n\nexport interface PerfOutput {\n type: 'connection' | 'stream' | 'intermediary' | 'final'\n timeSeconds: number\n uploadBytes: number\n downloadBytes: number\n}\n\nexport interface PerfInit {\n protocolName?: string\n maxInboundStreams?: number\n maxOutboundStreams?: number\n runOnLimitedConnection?: boolean\n\n /**\n * Data sent/received will be sent in chunks of this size\n *\n * @default 65536\n */\n writeBlockSize?: number\n}\n\nexport interface PerfComponents {\n registrar: Registrar\n connectionManager: ConnectionManager\n logger: ComponentLogger\n}\n\nexport function perf (init: PerfInit = {}): (components: PerfComponents) => Perf {\n return (components) => new PerfClass(components, init)\n}\n", "export default function pDefer() {\n\tconst deferred = {};\n\n\tdeferred.promise = new Promise((resolve, reject) => {\n\t\tdeferred.resolve = resolve;\n\t\tdeferred.reject = reject;\n\t});\n\n\treturn deferred;\n}\n", "// ported from https://www.npmjs.com/package/fast-fifo\n\nexport interface Next<T> {\n done?: boolean\n error?: Error\n value?: T\n}\n\nclass FixedFIFO<T> {\n public buffer: Array<Next<T> | undefined>\n private readonly mask: number\n private top: number\n private btm: number\n public next: FixedFIFO<T> | null\n\n constructor (hwm: number) {\n if (!(hwm > 0) || ((hwm - 1) & hwm) !== 0) {\n throw new Error('Max size for a FixedFIFO should be a power of two')\n }\n\n this.buffer = new Array(hwm)\n this.mask = hwm - 1\n this.top = 0\n this.btm = 0\n this.next = null\n }\n\n push (data: Next<T>): boolean {\n if (this.buffer[this.top] !== undefined) {\n return false\n }\n\n this.buffer[this.top] = data\n this.top = (this.top + 1) & this.mask\n\n return true\n }\n\n shift (): Next<T> | undefined {\n const last = this.buffer[this.btm]\n\n if (last === undefined) {\n return undefined\n }\n\n this.buffer[this.btm] = undefined\n this.btm = (this.btm + 1) & this.mask\n return last\n }\n\n isEmpty (): boolean {\n return this.buffer[this.btm] === undefined\n }\n}\n\nexport interface FIFOOptions {\n /**\n * When the queue reaches this size, it will be split into head/tail parts\n */\n splitLimit?: number\n}\n\nexport class FIFO<T> {\n public size: number\n private readonly hwm: number\n private head: FixedFIFO<T>\n private tail: FixedFIFO<T>\n\n constructor (options: FIFOOptions = {}) {\n this.hwm = options.splitLimit ?? 16\n this.head = new FixedFIFO<T>(this.hwm)\n this.tail = this.head\n this.size = 0\n }\n\n calculateSize (obj: any): number {\n if (obj?.byteLength != null) {\n return obj.byteLength\n }\n\n return 1\n }\n\n push (val: Next<T>): void {\n if (val?.value != null) {\n this.size += this.calculateSize(val.value)\n }\n\n if (!this.head.push(val)) {\n const prev = this.head\n this.head = prev.next = new FixedFIFO<T>(2 * this.head.buffer.length)\n this.head.push(val)\n }\n }\n\n shift (): Next<T> | undefined {\n let val = this.tail.shift()\n\n if (val === undefined && (this.tail.next != null)) {\n const next = this.tail.next\n this.tail.next = null\n this.tail = next\n val = this.tail.shift()\n }\n\n if (val?.value != null) {\n this.size -= this.calculateSize(val.value)\n }\n\n return val\n }\n\n isEmpty (): boolean {\n return this.head.isEmpty()\n }\n}\n", "/**\n * @packageDocumentation\n *\n * An iterable that you can push values into.\n *\n * @example\n *\n * ```js\n * import { pushable } from 'it-pushable'\n *\n * const source = pushable()\n *\n * setTimeout(() => source.push('hello'), 100)\n * setTimeout(() => source.push('world'), 200)\n * setTimeout(() => source.end(), 300)\n *\n * const start = Date.now()\n *\n * for await (const value of source) {\n * console.log(`got \"${value}\" after ${Date.now() - start}ms`)\n * }\n * console.log(`done after ${Date.now() - start}ms`)\n *\n * // Output:\n * // got \"hello\" after 105ms\n * // got \"world\" after 207ms\n * // done after 309ms\n * ```\n *\n * @example\n *\n * ```js\n * import { pushableV } from 'it-pushable'\n * import all from 'it-all'\n *\n * const source = pushableV()\n *\n * source.push(1)\n * source.push(2)\n * source.push(3)\n * source.end()\n *\n * console.info(await all(source))\n *\n * // Output:\n * // [ [1, 2, 3] ]\n * ```\n */\n\nimport deferred from 'p-defer'\nimport { FIFO, type Next } from './fifo.js'\n\nexport class AbortError extends Error {\n type: string\n code: string\n\n constructor (message?: string, code?: string) {\n super(message ?? 'The operation was aborted')\n this.type = 'aborted'\n this.code = code ?? 'ABORT_ERR'\n }\n}\n\nexport interface AbortOptions {\n signal?: AbortSignal\n}\n\ninterface BasePushable<T> {\n /**\n * End the iterable after all values in the buffer (if any) have been yielded. If an\n * error is passed the buffer is cleared immediately and the next iteration will\n * throw the passed error\n */\n end(err?: Error): this\n\n /**\n * Push a value into the iterable. Values are yielded from the iterable in the order\n * they are pushed. Values not yet consumed from the iterable are buffered.\n */\n push(value: T): this\n\n /**\n * Returns a promise that resolves when the underlying queue becomes empty (e.g.\n * this.readableLength === 0).\n *\n * If an AbortSignal is passed as an option and that signal aborts, it only\n * causes the returned promise to reject - it does not end the pushable.\n */\n onEmpty(options?: AbortOptions): Promise<void>\n\n /**\n * This property contains the number of bytes (or objects) in the queue ready to be read.\n *\n * If `objectMode` is true, this is the number of objects in the queue, if false it's the\n * total number of bytes in the queue.\n */\n readableLength: number\n}\n\n/**\n * An iterable that you can push values into.\n */\nexport interface Pushable<T, R = void, N = unknown> extends AsyncGenerator<T, R, N>, BasePushable<T> {}\n\n/**\n * Similar to `pushable`, except it yields multiple buffered chunks at a time. All values yielded from the iterable will be arrays.\n */\nexport interface PushableV<T, R = void, N = unknown> extends AsyncGenerator<T[], R, N>, BasePushable<T> {}\n\nexport interface Options {\n /**\n * A boolean value that means non-`Uint8Array`s will be passed to `.push`, default: `false`\n */\n objectMode?: boolean\n\n /**\n * A function called after *all* values have been yielded from the iterator (including\n * buffered values). In the case when the iterator is ended with an error it will be\n * passed the error as a parameter.\n */\n onEnd?(err?: Error): void\n}\n\nexport interface DoneResult { done: true }\nexport interface ValueResult<T> { done: false, value: T }\nexport type NextResult<T> = ValueResult<T> | DoneResult\n\ninterface getNext<T, V = T> { (buffer: FIFO<T>): NextResult<V> }\n\nexport interface ObjectPushableOptions extends Options {\n objectMode: true\n}\n\nexport interface BytePushableOptions extends Options {\n objectMode?: false\n}\n\n/**\n * Create a new async iterable. The values yielded from calls to `.next()`\n * or when used in a `for await of`loop are \"pushed\" into the iterable.\n * Returns an async iterable object with additional methods.\n */\nexport function pushable<T extends { byteLength: number } = Uint8Array> (options?: BytePushableOptions): Pushable<T>\nexport function pushable<T> (options: ObjectPushableOptions): Pushable<T>\nexport function pushable<T> (options: Options = {}): Pushable<T> {\n const getNext = (buffer: FIFO<T>): NextResult<T> => {\n const next: Next<T> | undefined = buffer.shift()\n\n if (next == null) {\n return { done: true }\n }\n\n if (next.error != null) {\n throw next.error\n }\n\n return {\n done: next.done === true,\n // @ts-expect-error if done is false, value will be present\n value: next.value\n }\n }\n\n return _pushable<T, T, Pushable<T>>(getNext, options)\n}\n\nexport function pushableV<T extends { byteLength: number } = Uint8Array> (options?: BytePushableOptions): PushableV<T>\nexport function pushableV<T> (options: ObjectPushableOptions): PushableV<T>\nexport function pushableV<T> (options: Options = {}): PushableV<T> {\n const getNext = (buffer: FIFO<T>): NextResult<T[]> => {\n let next: Next<T> | undefined\n const values: T[] = []\n\n while (!buffer.isEmpty()) {\n next = buffer.shift()\n\n if (next == null) {\n break\n }\n\n if (next.error != null) {\n throw next.error\n }\n\n if (next.done === false) {\n // @ts-expect-error if done is false value should be pushed\n values.push(next.value)\n }\n }\n\n if (next == null) {\n return { done: true }\n }\n\n return {\n done: next.done === true,\n value: values\n }\n }\n\n return _pushable<T, T[], PushableV<T>>(getNext, options)\n}\n\nfunction _pushable<PushType, ValueType, ReturnType> (getNext: getNext<PushType, ValueType>, options?: Options): ReturnType {\n options = options ?? {}\n let onEnd = options.onEnd\n let buffer = new FIFO<PushType>()\n let pushable: any\n let onNext: ((next: Next<PushType>) => ReturnType) | null\n let ended: boolean\n let drain = deferred()\n\n const waitNext = async (): Promise<NextResult<ValueType>> => {\n try {\n if (!buffer.isEmpty()) {\n return getNext(buffer)\n }\n\n if (ended) {\n return { done: true }\n }\n\n return await new Promise<NextResult<ValueType>>((resolve, reject) => {\n onNext = (next: Next<PushType>) => {\n onNext = null\n buffer.push(next)\n\n try {\n resolve(getNext(buffer))\n } catch (err) {\n reject(err)\n }\n\n return pushable\n }\n })\n } finally {\n if (buffer.isEmpty()) {\n // settle promise in the microtask queue to give consumers a chance to\n // await after calling .push\n queueMicrotask(() => {\n drain.resolve()\n drain = deferred()\n })\n }\n }\n }\n\n const bufferNext = (next: Next<PushType>): ReturnType => {\n if (onNext != null) {\n return onNext(next)\n }\n\n buffer.push(next)\n return pushable\n }\n\n const bufferError = (err: Error): ReturnType => {\n buffer = new FIFO()\n\n if (onNext != null) {\n return onNext({ error: err })\n }\n\n buffer.push({ error: err })\n return pushable\n }\n\n const push = (value: PushType): ReturnType => {\n if (ended) {\n return pushable\n }\n\n // @ts-expect-error `byteLength` is not declared on PushType\n if (options?.objectMode !== true && value?.byteLength == null) {\n throw new Error('objectMode was not true but tried to push non-Uint8Array value')\n }\n\n return bufferNext({ done: false, value })\n }\n const end = (err?: Error): ReturnType => {\n if (ended) return pushable\n ended = true\n\n return (err != null) ? bufferError(err) : bufferNext({ done: true })\n }\n const _return = (): DoneResult => {\n buffer = new FIFO()\n end()\n\n return { done: true }\n }\n const _throw = (err: Error): DoneResult => {\n end(err)\n\n return { done: true }\n }\n\n pushable = {\n [Symbol.asyncIterator] () { return this },\n next: waitNext,\n return: _return,\n throw: _throw,\n push,\n end,\n get readableLength (): number {\n return buffer.size\n },\n onEmpty: async (options?: AbortOptions) => {\n const signal = options?.signal\n signal?.throwIfAborted()\n\n if (buffer.isEmpty()) {\n return\n }\n\n let cancel: Promise<void> | undefined\n let listener: (() => void) | undefined\n\n if (signal != null) {\n cancel = new Promise((resolve, reject) => {\n listener = () => {\n reject(new AbortError())\n }\n\n signal.addEventListener('abort', listener)\n })\n }\n\n try {\n await Promise.race([\n drain.promise,\n cancel\n ])\n } finally {\n if (listener != null && signal != null) {\n signal?.removeEventListener('abort', listener)\n }\n }\n }\n }\n\n if (onEnd == null) {\n return pushable\n }\n\n const _pushable = pushable\n\n pushable = {\n [Symbol.asyncIterator] () { return this },\n next () {\n return _pushable.next()\n },\n throw (err: Error) {\n _pushable.throw(err)\n\n if (onEnd != null) {\n onEnd(err)\n onEnd = undefined\n }\n\n return { done: true }\n },\n return () {\n _pushable.return()\n\n if (onEnd != null) {\n onEnd()\n onEnd = undefined\n }\n\n return { done: true }\n },\n push,\n end (err: Error) {\n _pushable.end(err)\n\n if (onEnd != null) {\n onEnd(err)\n onEnd = undefined\n }\n\n return pushable\n },\n get readableLength () {\n return _pushable.readableLength\n },\n onEmpty: (opts?: AbortOptions) => {\n return _pushable.onEmpty(opts)\n }\n }\n\n return pushable\n}\n", "export const PROTOCOL_NAME = '/perf/1.0.0'\nexport const WRITE_BLOCK_SIZE = 64 << 10\nexport const MAX_INBOUND_STREAMS = 1\nexport const MAX_OUTBOUND_STREAMS = 1\nexport const RUN_ON_LIMITED_CONNECTION = false\n", "import { pushable } from 'it-pushable'\nimport { MAX_INBOUND_STREAMS, MAX_OUTBOUND_STREAMS, PROTOCOL_NAME, RUN_ON_LIMITED_CONNECTION, WRITE_BLOCK_SIZE } from './constants.js'\nimport type { PerfOptions, PerfOutput, PerfComponents, PerfInit, Perf as PerfInterface } from './index.js'\nimport type { Logger, Startable, IncomingStreamData } from '@libp2p/interface'\nimport type { Multiaddr } from '@multiformats/multiaddr'\n\nexport class Perf implements Startable, PerfInterface {\n private readonly log: Logger\n public readonly protocol: string\n private readonly components: PerfComponents\n private started: boolean\n private readonly buf: ArrayBuffer\n private readonly writeBlockSize: number\n private readonly maxInboundStreams: number\n private readonly maxOutboundStreams: number\n private readonly runOnLimitedConnection: boolean\n\n constructor (components: PerfComponents, init: PerfInit = {}) {\n this.components = components\n this.log = components.logger.forComponent('libp2p:perf')\n this.started = false\n this.protocol = init.protocolName ?? PROTOCOL_NAME\n this.writeBlockSize = init.writeBlockSize ?? WRITE_BLOCK_SIZE\n this.buf = new ArrayBuffer(this.writeBlockSize)\n this.maxInboundStreams = init.maxInboundStreams ?? MAX_INBOUND_STREAMS\n this.maxOutboundStreams = init.maxOutboundStreams ?? MAX_OUTBOUND_STREAMS\n this.runOnLimitedConnection = init.runOnLimitedConnection ?? RUN_ON_LIMITED_CONNECTION\n }\n\n readonly [Symbol.toStringTag] = '@libp2p/perf'\n\n async start (): Promise<void> {\n await this.components.registrar.handle(this.protocol, (data: IncomingStreamData) => {\n void this.handleMessage(data).catch((err) => {\n this.log.error('error handling perf protocol message - %e', err)\n })\n }, {\n maxInboundStreams: this.maxInboundStreams,\n maxOutboundStreams: this.maxOutboundStreams,\n runOnLimitedConnection: this.runOnLimitedConnection\n })\n this.started = true\n }\n\n async stop (): Promise<void> {\n await this.components.registrar.unhandle(this.protocol)\n this.started = false\n }\n\n isStarted (): boolean {\n return this.started\n }\n\n async handleMessage (data: IncomingStreamData): Promise<void> {\n const { stream } = data\n\n try {\n const writeBlockSize = this.writeBlockSize\n\n let bytesToSendBack: number | undefined\n\n for await (const buf of stream.source) {\n if (bytesToSendBack == null) {\n // downcast 64 to 52 bits to avoid bigint arithmetic performance penalty\n bytesToSendBack = Number(buf.getBigUint64(0, false))\n }\n\n // Ingest all the data and wait for the read side to close\n }\n\n if (bytesToSendBack == null) {\n throw new Error('bytesToSendBack was not set')\n }\n\n const uint8Buf = new Uint8Array(this.buf, 0, this.buf.byteLength)\n\n await stream.sink(async function * () {\n while (bytesToSendBack > 0) {\n let toSend: number = writeBlockSize\n if (toSend > bytesToSendBack) {\n toSend = bytesToSendBack\n }\n\n bytesToSendBack = bytesToSendBack - toSend\n yield uint8Buf.subarray(0, toSend)\n }\n }())\n } catch (err: any) {\n stream.abort(err)\n }\n }\n\n async * measurePerformance (ma: Multiaddr, sendBytes: number, receiveBytes: number, options: PerfOptions = {}): AsyncGenerator<PerfOutput> {\n const uint8Buf = new Uint8Array(this.buf)\n const writeBlockSize = this.writeBlockSize\n\n const initialStartTime = Date.now()\n let lastReportedTime = Date.now()\n const connection = await this.components.connectionManager.openConnection(ma, {\n ...options,\n force: options.reuseExistingConnection !== true\n })\n\n const log = connection.log.newScope('perf')\n\n log('opened connection after %d ms', Date.now() - lastReportedTime)\n lastReportedTime = Date.now()\n\n const stream = await connection.newStream(this.protocol, options)\n\n log('opened stream after %d ms', Date.now() - lastReportedTime)\n lastReportedTime = Date.now()\n\n let lastAmountOfBytesSent = 0\n let totalBytesSent = 0\n const uploadStart = Date.now()\n\n // tell the remote how many bytes we will send. Up cast to 64 bit number\n // as if we send as ui32 we limit total transfer size to 4GB\n const view = new DataView(this.buf)\n view.setBigUint64(0, BigInt(receiveBytes), false)\n\n log('sending %i bytes to %p', sendBytes, connection.remotePeer)\n\n try {\n const output = pushable<PerfOutput>({\n objectMode: true\n })\n\n stream.sink(async function * () {\n yield uint8Buf.subarray(0, 8)\n\n while (sendBytes > 0) {\n let toSend: number = writeBlockSize\n\n if (toSend > sendBytes) {\n toSend = sendBytes\n }\n\n yield uint8Buf.subarray(0, toSend)\n\n sendBytes -= toSend\n\n if (Date.now() - lastReportedTime > 1000) {\n output.push({\n type: 'intermediary',\n timeSeconds: (Date.now() - lastReportedTime) / 1000,\n uploadBytes: lastAmountOfBytesSent,\n downloadBytes: 0\n })\n\n // record last reported time after `console.log` because it can\n // affect benchmark timings\n lastReportedTime = Date.now()\n lastAmountOfBytesSent = 0\n }\n\n lastAmountOfBytesSent += toSend\n totalBytesSent += toSend\n }\n\n output.end()\n }())\n .catch(err => {\n output.end(err)\n })\n\n yield * output\n\n log('upload complete after %d ms', Date.now() - uploadStart)\n\n // Read the received bytes\n let lastAmountOfBytesReceived = 0\n lastReportedTime = Date.now()\n let totalBytesReceived = 0\n const downloadStart = Date.now()\n\n for await (const buf of stream.source) {\n if (Date.now() - lastReportedTime > 1000) {\n yield {\n type: 'intermediary',\n timeSeconds: (Date.now() - lastReportedTime) / 1000,\n uploadBytes: 0,\n downloadBytes: lastAmountOfBytesReceived\n }\n\n // record last reported time after `console.log` because it can\n // affect benchmark timings\n lastReportedTime = Date.now()\n lastAmountOfBytesReceived = 0\n }\n\n lastAmountOfBytesReceived += buf.byteLength\n totalBytesReceived += buf.byteLength\n }\n\n log('download complete after %d ms', Date.now() - downloadStart)\n\n if (totalBytesReceived !== receiveBytes) {\n throw new Error(`Expected to receive ${receiveBytes} bytes, but received ${totalBytesReceived}`)\n }\n\n yield {\n type: 'final',\n timeSeconds: (Date.now() - initialStartTime) / 1000,\n uploadBytes: totalBytesSent,\n downloadBytes: totalBytesReceived\n }\n\n log('performed %s to %p', this.protocol, connection.remotePeer)\n await stream.close()\n } catch (err: any) {\n log('error sending %d/%d bytes to %p: %s', totalBytesSent, sendBytes, connection.remotePeer, err)\n stream.abort(err)\n throw err\n }\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["index_exports", "__export", "perf", "pDefer", "deferred", "resolve", "reject", "FixedFIFO", "hwm", "data", "last", "FIFO", "options", "obj", "val", "prev", "next", "AbortError", "message", "code", "pushable", "options", "_pushable", "buffer", "next", "_pushable", "getNext", "options", "onEnd", "buffer", "FIFO", "pushable", "onNext", "ended", "drain", "pDefer", "waitNext", "resolve", "reject", "next", "err", "bufferNext", "bufferError", "push", "value", "end", "_return", "_throw", "signal", "cancel", "listener", "AbortError", "opts", "PROTOCOL_NAME", "Perf", "components", "init", "PROTOCOL_NAME", "data", "err", "stream", "writeBlockSize", "bytesToSendBack", "buf", "uint8Buf", "toSend", "ma", "sendBytes", "receiveBytes", "options", "initialStartTime", "lastReportedTime", "connection", "log", "lastAmountOfBytesSent", "totalBytesSent", "uploadStart", "output", "pushable", "lastAmountOfBytesReceived", "totalBytesReceived", "downloadStart", "perf", "init", "components", "Perf"]
3
+ "sources": ["../src/index.ts", "../../../node_modules/p-defer/index.js", "../../../node_modules/it-pushable/src/fifo.ts", "../../../node_modules/it-pushable/src/index.ts", "../../../node_modules/p-timeout/index.js", "../../../node_modules/p-event/index.js", "../../../node_modules/uint8arrays/src/alloc.ts", "../../../node_modules/uint8arrays/src/concat.ts", "../../../node_modules/uint8arrays/src/equals.ts", "../../../node_modules/uint8arraylist/src/index.ts", "../src/constants.ts", "../src/perf-service.ts"],
4
+ "sourcesContent": ["/**\n * @packageDocumentation\n *\n * The {@link Perf} service implements the [perf protocol](https://github.com/libp2p/specs/blob/master/perf/perf.md), which can be used to measure transfer performance within and across libp2p implementations.\n *\n * @example\n *\n * ```typescript\n * import { noise } from '@libp2p/noise'\n * import { yamux } from '@libp2p/yamux'\n * import { tcp } from '@libp2p/tcp'\n * import { createLibp2p, type Libp2p } from 'libp2p'\n * import { plaintext } from '@libp2p/plaintext'\n * import { perf, type Perf } from '@libp2p/perf'\n *\n * const ONE_MEG = 1024 * 1024\n * const UPLOAD_BYTES = ONE_MEG * 1024\n * const DOWNLOAD_BYTES = ONE_MEG * 1024\n *\n * async function createNode (): Promise<Libp2p<{ perf: Perf }>> {\n * return createLibp2p({\n * addresses: {\n * listen: [\n * '/ip4/0.0.0.0/tcp/0'\n * ]\n * },\n * transports: [\n * tcp()\n * ],\n * connectionEncrypters: [\n * noise(), plaintext()\n * ],\n * streamMuxers: [\n * yamux()\n * ],\n * services: {\n * perf: perf()\n * }\n * })\n * }\n *\n * const libp2p1 = await createNode()\n * const libp2p2 = await createNode()\n *\n * for await (const output of libp2p1.services.perf.measurePerformance(libp2p2.getMultiaddrs()[0], UPLOAD_BYTES, DOWNLOAD_BYTES)) {\n * console.info(output)\n * }\n *\n * await libp2p1.stop()\n * await libp2p2.stop()\n * ```\n */\n\nimport { Perf as PerfClass } from './perf-service.js'\nimport type { AbortOptions, ComponentLogger } from '@libp2p/interface'\nimport type { ConnectionManager, Registrar } from '@libp2p/interface-internal'\nimport type { Multiaddr } from '@multiformats/multiaddr'\n\nexport interface PerfOptions extends AbortOptions {\n /**\n * By default measuring perf should include the time it takes to establish a\n * connection, so a new connection will be opened for every performance run.\n *\n * To override this and re-use an existing connection if one is present, pass\n * `true` here.\n *\n * @default false\n */\n reuseExistingConnection?: boolean\n}\n\nexport interface Perf {\n measurePerformance(multiaddr: Multiaddr, sendBytes: number, recvBytes: number, options?: PerfOptions): AsyncGenerator<PerfOutput>\n}\n\nexport interface PerfOutput {\n type: 'connection' | 'stream' | 'intermediary' | 'final'\n timeSeconds: number\n uploadBytes: number\n downloadBytes: number\n}\n\nexport interface PerfInit {\n protocolName?: string\n maxInboundStreams?: number\n maxOutboundStreams?: number\n runOnLimitedConnection?: boolean\n\n /**\n * Data sent/received will be sent in chunks of this size\n *\n * @default 65536\n */\n writeBlockSize?: number\n}\n\nexport interface PerfComponents {\n registrar: Registrar\n connectionManager: ConnectionManager\n logger: ComponentLogger\n}\n\nexport function perf (init: PerfInit = {}): (components: PerfComponents) => Perf {\n return (components) => new PerfClass(components, init)\n}\n", "export default function pDefer() {\n\tconst deferred = {};\n\n\tdeferred.promise = new Promise((resolve, reject) => {\n\t\tdeferred.resolve = resolve;\n\t\tdeferred.reject = reject;\n\t});\n\n\treturn deferred;\n}\n", "// ported from https://www.npmjs.com/package/fast-fifo\n\nexport interface Next<T> {\n done?: boolean\n error?: Error\n value?: T\n}\n\nclass FixedFIFO<T> {\n public buffer: Array<Next<T> | undefined>\n private readonly mask: number\n private top: number\n private btm: number\n public next: FixedFIFO<T> | null\n\n constructor (hwm: number) {\n if (!(hwm > 0) || ((hwm - 1) & hwm) !== 0) {\n throw new Error('Max size for a FixedFIFO should be a power of two')\n }\n\n this.buffer = new Array(hwm)\n this.mask = hwm - 1\n this.top = 0\n this.btm = 0\n this.next = null\n }\n\n push (data: Next<T>): boolean {\n if (this.buffer[this.top] !== undefined) {\n return false\n }\n\n this.buffer[this.top] = data\n this.top = (this.top + 1) & this.mask\n\n return true\n }\n\n shift (): Next<T> | undefined {\n const last = this.buffer[this.btm]\n\n if (last === undefined) {\n return undefined\n }\n\n this.buffer[this.btm] = undefined\n this.btm = (this.btm + 1) & this.mask\n return last\n }\n\n isEmpty (): boolean {\n return this.buffer[this.btm] === undefined\n }\n}\n\nexport interface FIFOOptions {\n /**\n * When the queue reaches this size, it will be split into head/tail parts\n */\n splitLimit?: number\n}\n\nexport class FIFO<T> {\n public size: number\n private readonly hwm: number\n private head: FixedFIFO<T>\n private tail: FixedFIFO<T>\n\n constructor (options: FIFOOptions = {}) {\n this.hwm = options.splitLimit ?? 16\n this.head = new FixedFIFO<T>(this.hwm)\n this.tail = this.head\n this.size = 0\n }\n\n calculateSize (obj: any): number {\n if (obj?.byteLength != null) {\n return obj.byteLength\n }\n\n return 1\n }\n\n push (val: Next<T>): void {\n if (val?.value != null) {\n this.size += this.calculateSize(val.value)\n }\n\n if (!this.head.push(val)) {\n const prev = this.head\n this.head = prev.next = new FixedFIFO<T>(2 * this.head.buffer.length)\n this.head.push(val)\n }\n }\n\n shift (): Next<T> | undefined {\n let val = this.tail.shift()\n\n if (val === undefined && (this.tail.next != null)) {\n const next = this.tail.next\n this.tail.next = null\n this.tail = next\n val = this.tail.shift()\n }\n\n if (val?.value != null) {\n this.size -= this.calculateSize(val.value)\n }\n\n return val\n }\n\n isEmpty (): boolean {\n return this.head.isEmpty()\n }\n}\n", "/**\n * @packageDocumentation\n *\n * An iterable that you can push values into.\n *\n * @example\n *\n * ```js\n * import { pushable } from 'it-pushable'\n *\n * const source = pushable()\n *\n * setTimeout(() => source.push('hello'), 100)\n * setTimeout(() => source.push('world'), 200)\n * setTimeout(() => source.end(), 300)\n *\n * const start = Date.now()\n *\n * for await (const value of source) {\n * console.log(`got \"${value}\" after ${Date.now() - start}ms`)\n * }\n * console.log(`done after ${Date.now() - start}ms`)\n *\n * // Output:\n * // got \"hello\" after 105ms\n * // got \"world\" after 207ms\n * // done after 309ms\n * ```\n *\n * @example\n *\n * ```js\n * import { pushableV } from 'it-pushable'\n * import all from 'it-all'\n *\n * const source = pushableV()\n *\n * source.push(1)\n * source.push(2)\n * source.push(3)\n * source.end()\n *\n * console.info(await all(source))\n *\n * // Output:\n * // [ [1, 2, 3] ]\n * ```\n */\n\nimport deferred from 'p-defer'\nimport { FIFO, type Next } from './fifo.js'\n\nexport class AbortError extends Error {\n type: string\n code: string\n\n constructor (message?: string, code?: string) {\n super(message ?? 'The operation was aborted')\n this.type = 'aborted'\n this.code = code ?? 'ABORT_ERR'\n }\n}\n\nexport interface AbortOptions {\n signal?: AbortSignal\n}\n\ninterface BasePushable<T> {\n /**\n * End the iterable after all values in the buffer (if any) have been yielded. If an\n * error is passed the buffer is cleared immediately and the next iteration will\n * throw the passed error\n */\n end(err?: Error): this\n\n /**\n * Push a value into the iterable. Values are yielded from the iterable in the order\n * they are pushed. Values not yet consumed from the iterable are buffered.\n */\n push(value: T): this\n\n /**\n * Returns a promise that resolves when the underlying queue becomes empty (e.g.\n * this.readableLength === 0).\n *\n * If an AbortSignal is passed as an option and that signal aborts, it only\n * causes the returned promise to reject - it does not end the pushable.\n */\n onEmpty(options?: AbortOptions): Promise<void>\n\n /**\n * This property contains the number of bytes (or objects) in the queue ready to be read.\n *\n * If `objectMode` is true, this is the number of objects in the queue, if false it's the\n * total number of bytes in the queue.\n */\n readableLength: number\n}\n\n/**\n * An iterable that you can push values into.\n */\nexport interface Pushable<T, R = void, N = unknown> extends AsyncGenerator<T, R, N>, BasePushable<T> {}\n\n/**\n * Similar to `pushable`, except it yields multiple buffered chunks at a time. All values yielded from the iterable will be arrays.\n */\nexport interface PushableV<T, R = void, N = unknown> extends AsyncGenerator<T[], R, N>, BasePushable<T> {}\n\nexport interface Options {\n /**\n * A boolean value that means non-`Uint8Array`s will be passed to `.push`, default: `false`\n */\n objectMode?: boolean\n\n /**\n * A function called after *all* values have been yielded from the iterator (including\n * buffered values). In the case when the iterator is ended with an error it will be\n * passed the error as a parameter.\n */\n onEnd?(err?: Error): void\n}\n\nexport interface DoneResult { done: true }\nexport interface ValueResult<T> { done: false, value: T }\nexport type NextResult<T> = ValueResult<T> | DoneResult\n\ninterface getNext<T, V = T> { (buffer: FIFO<T>): NextResult<V> }\n\nexport interface ObjectPushableOptions extends Options {\n objectMode: true\n}\n\nexport interface BytePushableOptions extends Options {\n objectMode?: false\n}\n\n/**\n * Create a new async iterable. The values yielded from calls to `.next()`\n * or when used in a `for await of`loop are \"pushed\" into the iterable.\n * Returns an async iterable object with additional methods.\n */\nexport function pushable<T extends { byteLength: number } = Uint8Array> (options?: BytePushableOptions): Pushable<T>\nexport function pushable<T> (options: ObjectPushableOptions): Pushable<T>\nexport function pushable<T> (options: Options = {}): Pushable<T> {\n const getNext = (buffer: FIFO<T>): NextResult<T> => {\n const next: Next<T> | undefined = buffer.shift()\n\n if (next == null) {\n return { done: true }\n }\n\n if (next.error != null) {\n throw next.error\n }\n\n return {\n done: next.done === true,\n // @ts-expect-error if done is false, value will be present\n value: next.value\n }\n }\n\n return _pushable<T, T, Pushable<T>>(getNext, options)\n}\n\nexport function pushableV<T extends { byteLength: number } = Uint8Array> (options?: BytePushableOptions): PushableV<T>\nexport function pushableV<T> (options: ObjectPushableOptions): PushableV<T>\nexport function pushableV<T> (options: Options = {}): PushableV<T> {\n const getNext = (buffer: FIFO<T>): NextResult<T[]> => {\n let next: Next<T> | undefined\n const values: T[] = []\n\n while (!buffer.isEmpty()) {\n next = buffer.shift()\n\n if (next == null) {\n break\n }\n\n if (next.error != null) {\n throw next.error\n }\n\n if (next.done === false) {\n // @ts-expect-error if done is false value should be pushed\n values.push(next.value)\n }\n }\n\n if (next == null) {\n return { done: true }\n }\n\n return {\n done: next.done === true,\n value: values\n }\n }\n\n return _pushable<T, T[], PushableV<T>>(getNext, options)\n}\n\nfunction _pushable<PushType, ValueType, ReturnType> (getNext: getNext<PushType, ValueType>, options?: Options): ReturnType {\n options = options ?? {}\n let onEnd = options.onEnd\n let buffer = new FIFO<PushType>()\n let pushable: any\n let onNext: ((next: Next<PushType>) => ReturnType) | null\n let ended: boolean\n let drain = deferred()\n\n const waitNext = async (): Promise<NextResult<ValueType>> => {\n try {\n if (!buffer.isEmpty()) {\n return getNext(buffer)\n }\n\n if (ended) {\n return { done: true }\n }\n\n return await new Promise<NextResult<ValueType>>((resolve, reject) => {\n onNext = (next: Next<PushType>) => {\n onNext = null\n buffer.push(next)\n\n try {\n resolve(getNext(buffer))\n } catch (err) {\n reject(err)\n }\n\n return pushable\n }\n })\n } finally {\n if (buffer.isEmpty()) {\n // settle promise in the microtask queue to give consumers a chance to\n // await after calling .push\n queueMicrotask(() => {\n drain.resolve()\n drain = deferred()\n })\n }\n }\n }\n\n const bufferNext = (next: Next<PushType>): ReturnType => {\n if (onNext != null) {\n return onNext(next)\n }\n\n buffer.push(next)\n return pushable\n }\n\n const bufferError = (err: Error): ReturnType => {\n buffer = new FIFO()\n\n if (onNext != null) {\n return onNext({ error: err })\n }\n\n buffer.push({ error: err })\n return pushable\n }\n\n const push = (value: PushType): ReturnType => {\n if (ended) {\n return pushable\n }\n\n // @ts-expect-error `byteLength` is not declared on PushType\n if (options?.objectMode !== true && value?.byteLength == null) {\n throw new Error('objectMode was not true but tried to push non-Uint8Array value')\n }\n\n return bufferNext({ done: false, value })\n }\n const end = (err?: Error): ReturnType => {\n if (ended) return pushable\n ended = true\n\n return (err != null) ? bufferError(err) : bufferNext({ done: true })\n }\n const _return = (): DoneResult => {\n buffer = new FIFO()\n end()\n\n return { done: true }\n }\n const _throw = (err: Error): DoneResult => {\n end(err)\n\n return { done: true }\n }\n\n pushable = {\n [Symbol.asyncIterator] () { return this },\n next: waitNext,\n return: _return,\n throw: _throw,\n push,\n end,\n get readableLength (): number {\n return buffer.size\n },\n onEmpty: async (options?: AbortOptions) => {\n const signal = options?.signal\n signal?.throwIfAborted()\n\n if (buffer.isEmpty()) {\n return\n }\n\n let cancel: Promise<void> | undefined\n let listener: (() => void) | undefined\n\n if (signal != null) {\n cancel = new Promise((resolve, reject) => {\n listener = () => {\n reject(new AbortError())\n }\n\n signal.addEventListener('abort', listener)\n })\n }\n\n try {\n await Promise.race([\n drain.promise,\n cancel\n ])\n } finally {\n if (listener != null && signal != null) {\n signal?.removeEventListener('abort', listener)\n }\n }\n }\n }\n\n if (onEnd == null) {\n return pushable\n }\n\n const _pushable = pushable\n\n pushable = {\n [Symbol.asyncIterator] () { return this },\n next () {\n return _pushable.next()\n },\n throw (err: Error) {\n _pushable.throw(err)\n\n if (onEnd != null) {\n onEnd(err)\n onEnd = undefined\n }\n\n return { done: true }\n },\n return () {\n _pushable.return()\n\n if (onEnd != null) {\n onEnd()\n onEnd = undefined\n }\n\n return { done: true }\n },\n push,\n end (err: Error) {\n _pushable.end(err)\n\n if (onEnd != null) {\n onEnd(err)\n onEnd = undefined\n }\n\n return pushable\n },\n get readableLength () {\n return _pushable.readableLength\n },\n onEmpty: (opts?: AbortOptions) => {\n return _pushable.onEmpty(opts)\n }\n }\n\n return pushable\n}\n", "export class TimeoutError extends Error {\n\tconstructor(message) {\n\t\tsuper(message);\n\t\tthis.name = 'TimeoutError';\n\t}\n}\n\n/**\nAn error to be thrown when the request is aborted by AbortController.\nDOMException is thrown instead of this Error when DOMException is available.\n*/\nexport class AbortError extends Error {\n\tconstructor(message) {\n\t\tsuper();\n\t\tthis.name = 'AbortError';\n\t\tthis.message = message;\n\t}\n}\n\n/**\nTODO: Remove AbortError and just throw DOMException when targeting Node 18.\n*/\nconst getDOMException = errorMessage => globalThis.DOMException === undefined\n\t? new AbortError(errorMessage)\n\t: new DOMException(errorMessage);\n\n/**\nTODO: Remove below function and just 'reject(signal.reason)' when targeting Node 18.\n*/\nconst getAbortedReason = signal => {\n\tconst reason = signal.reason === undefined\n\t\t? getDOMException('This operation was aborted.')\n\t\t: signal.reason;\n\n\treturn reason instanceof Error ? reason : getDOMException(reason);\n};\n\nexport default function pTimeout(promise, options) {\n\tconst {\n\t\tmilliseconds,\n\t\tfallback,\n\t\tmessage,\n\t\tcustomTimers = {setTimeout, clearTimeout},\n\t} = options;\n\n\tlet timer;\n\tlet abortHandler;\n\n\tconst wrappedPromise = new Promise((resolve, reject) => {\n\t\tif (typeof milliseconds !== 'number' || Math.sign(milliseconds) !== 1) {\n\t\t\tthrow new TypeError(`Expected \\`milliseconds\\` to be a positive number, got \\`${milliseconds}\\``);\n\t\t}\n\n\t\tif (options.signal) {\n\t\t\tconst {signal} = options;\n\t\t\tif (signal.aborted) {\n\t\t\t\treject(getAbortedReason(signal));\n\t\t\t}\n\n\t\t\tabortHandler = () => {\n\t\t\t\treject(getAbortedReason(signal));\n\t\t\t};\n\n\t\t\tsignal.addEventListener('abort', abortHandler, {once: true});\n\t\t}\n\n\t\tif (milliseconds === Number.POSITIVE_INFINITY) {\n\t\t\tpromise.then(resolve, reject);\n\t\t\treturn;\n\t\t}\n\n\t\t// We create the error outside of `setTimeout` to preserve the stack trace.\n\t\tconst timeoutError = new TimeoutError();\n\n\t\ttimer = customTimers.setTimeout.call(undefined, () => {\n\t\t\tif (fallback) {\n\t\t\t\ttry {\n\t\t\t\t\tresolve(fallback());\n\t\t\t\t} catch (error) {\n\t\t\t\t\treject(error);\n\t\t\t\t}\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (typeof promise.cancel === 'function') {\n\t\t\t\tpromise.cancel();\n\t\t\t}\n\n\t\t\tif (message === false) {\n\t\t\t\tresolve();\n\t\t\t} else if (message instanceof Error) {\n\t\t\t\treject(message);\n\t\t\t} else {\n\t\t\t\ttimeoutError.message = message ?? `Promise timed out after ${milliseconds} milliseconds`;\n\t\t\t\treject(timeoutError);\n\t\t\t}\n\t\t}, milliseconds);\n\n\t\t(async () => {\n\t\t\ttry {\n\t\t\t\tresolve(await promise);\n\t\t\t} catch (error) {\n\t\t\t\treject(error);\n\t\t\t}\n\t\t})();\n\t});\n\n\tconst cancelablePromise = wrappedPromise.finally(() => {\n\t\tcancelablePromise.clear();\n\t\tif (abortHandler && options.signal) {\n\t\t\toptions.signal.removeEventListener('abort', abortHandler);\n\t\t}\n\t});\n\n\tcancelablePromise.clear = () => {\n\t\tcustomTimers.clearTimeout.call(undefined, timer);\n\t\ttimer = undefined;\n\t};\n\n\treturn cancelablePromise;\n}\n", "import pTimeout from 'p-timeout';\n\nconst normalizeEmitter = emitter => {\n\tconst addListener = emitter.addEventListener || emitter.on || emitter.addListener;\n\tconst removeListener = emitter.removeEventListener || emitter.off || emitter.removeListener;\n\n\tif (!addListener || !removeListener) {\n\t\tthrow new TypeError('Emitter is not compatible');\n\t}\n\n\treturn {\n\t\taddListener: addListener.bind(emitter),\n\t\tremoveListener: removeListener.bind(emitter),\n\t};\n};\n\nexport function pEventMultiple(emitter, event, options) {\n\tlet cancel;\n\tconst returnValue = new Promise((resolve, reject) => {\n\t\toptions = {\n\t\t\trejectionEvents: ['error'],\n\t\t\tmultiArgs: false,\n\t\t\tresolveImmediately: false,\n\t\t\t...options,\n\t\t};\n\n\t\tif (!(options.count >= 0 && (options.count === Number.POSITIVE_INFINITY || Number.isInteger(options.count)))) {\n\t\t\tthrow new TypeError('The `count` option should be at least 0 or more');\n\t\t}\n\n\t\toptions.signal?.throwIfAborted();\n\n\t\t// Allow multiple events\n\t\tconst events = [event].flat();\n\n\t\tconst items = [];\n\t\tconst {addListener, removeListener} = normalizeEmitter(emitter);\n\n\t\tconst onItem = (...arguments_) => {\n\t\t\tconst value = options.multiArgs ? arguments_ : arguments_[0];\n\n\t\t\t// eslint-disable-next-line unicorn/no-array-callback-reference\n\t\t\tif (options.filter && !options.filter(value)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\titems.push(value);\n\n\t\t\tif (options.count === items.length) {\n\t\t\t\tcancel();\n\t\t\t\tresolve(items);\n\t\t\t}\n\t\t};\n\n\t\tconst rejectHandler = error => {\n\t\t\tcancel();\n\t\t\treject(error);\n\t\t};\n\n\t\tcancel = () => {\n\t\t\tfor (const event of events) {\n\t\t\t\tremoveListener(event, onItem);\n\t\t\t}\n\n\t\t\tfor (const rejectionEvent of options.rejectionEvents) {\n\t\t\t\tremoveListener(rejectionEvent, rejectHandler);\n\t\t\t}\n\t\t};\n\n\t\tfor (const event of events) {\n\t\t\taddListener(event, onItem);\n\t\t}\n\n\t\tfor (const rejectionEvent of options.rejectionEvents) {\n\t\t\taddListener(rejectionEvent, rejectHandler);\n\t\t}\n\n\t\tif (options.signal) {\n\t\t\toptions.signal.addEventListener('abort', () => {\n\t\t\t\trejectHandler(options.signal.reason);\n\t\t\t}, {once: true});\n\t\t}\n\n\t\tif (options.resolveImmediately) {\n\t\t\tresolve(items);\n\t\t}\n\t});\n\n\treturnValue.cancel = cancel;\n\n\tif (typeof options.timeout === 'number') {\n\t\tconst timeout = pTimeout(returnValue, {milliseconds: options.timeout});\n\t\ttimeout.cancel = cancel;\n\t\treturn timeout;\n\t}\n\n\treturn returnValue;\n}\n\nexport function pEvent(emitter, event, options) {\n\tif (typeof options === 'function') {\n\t\toptions = {filter: options};\n\t}\n\n\toptions = {\n\t\t...options,\n\t\tcount: 1,\n\t\tresolveImmediately: false,\n\t};\n\n\tconst arrayPromise = pEventMultiple(emitter, event, options);\n\tconst promise = arrayPromise.then(array => array[0]);\n\tpromise.cancel = arrayPromise.cancel;\n\n\treturn promise;\n}\n\nexport function pEventIterator(emitter, event, options) {\n\tif (typeof options === 'function') {\n\t\toptions = {filter: options};\n\t}\n\n\t// Allow multiple events\n\tconst events = [event].flat();\n\n\toptions = {\n\t\trejectionEvents: ['error'],\n\t\tresolutionEvents: [],\n\t\tlimit: Number.POSITIVE_INFINITY,\n\t\tmultiArgs: false,\n\t\t...options,\n\t};\n\n\tconst {limit} = options;\n\tconst isValidLimit = limit >= 0 && (limit === Number.POSITIVE_INFINITY || Number.isInteger(limit));\n\tif (!isValidLimit) {\n\t\tthrow new TypeError('The `limit` option should be a non-negative integer or Infinity');\n\t}\n\n\toptions.signal?.throwIfAborted();\n\n\tif (limit === 0) {\n\t\t// Return an empty async iterator to avoid any further cost\n\t\treturn {\n\t\t\t[Symbol.asyncIterator]() {\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tasync next() {\n\t\t\t\treturn {\n\t\t\t\t\tdone: true,\n\t\t\t\t\tvalue: undefined,\n\t\t\t\t};\n\t\t\t},\n\t\t};\n\t}\n\n\tconst {addListener, removeListener} = normalizeEmitter(emitter);\n\n\tlet isDone = false;\n\tlet error;\n\tlet hasPendingError = false;\n\tconst nextQueue = [];\n\tconst valueQueue = [];\n\tlet eventCount = 0;\n\tlet isLimitReached = false;\n\n\tconst valueHandler = (...arguments_) => {\n\t\teventCount++;\n\t\tisLimitReached = eventCount === limit;\n\n\t\tconst value = options.multiArgs ? arguments_ : arguments_[0];\n\n\t\tif (nextQueue.length > 0) {\n\t\t\tconst {resolve} = nextQueue.shift();\n\n\t\t\tresolve({done: false, value});\n\n\t\t\tif (isLimitReached) {\n\t\t\t\tcancel();\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tvalueQueue.push(value);\n\n\t\tif (isLimitReached) {\n\t\t\tcancel();\n\t\t}\n\t};\n\n\tconst cancel = () => {\n\t\tisDone = true;\n\n\t\tfor (const event of events) {\n\t\t\tremoveListener(event, valueHandler);\n\t\t}\n\n\t\tfor (const rejectionEvent of options.rejectionEvents) {\n\t\t\tremoveListener(rejectionEvent, rejectHandler);\n\t\t}\n\n\t\tfor (const resolutionEvent of options.resolutionEvents) {\n\t\t\tremoveListener(resolutionEvent, resolveHandler);\n\t\t}\n\n\t\twhile (nextQueue.length > 0) {\n\t\t\tconst {resolve} = nextQueue.shift();\n\t\t\tresolve({done: true, value: undefined});\n\t\t}\n\t};\n\n\tconst rejectHandler = (...arguments_) => {\n\t\terror = options.multiArgs ? arguments_ : arguments_[0];\n\n\t\tif (nextQueue.length > 0) {\n\t\t\tconst {reject} = nextQueue.shift();\n\t\t\treject(error);\n\t\t} else {\n\t\t\thasPendingError = true;\n\t\t}\n\n\t\tcancel();\n\t};\n\n\tconst resolveHandler = (...arguments_) => {\n\t\tconst value = options.multiArgs ? arguments_ : arguments_[0];\n\n\t\t// eslint-disable-next-line unicorn/no-array-callback-reference\n\t\tif (options.filter && !options.filter(value)) {\n\t\t\tcancel();\n\t\t\treturn;\n\t\t}\n\n\t\tif (nextQueue.length > 0) {\n\t\t\tconst {resolve} = nextQueue.shift();\n\t\t\tresolve({done: true, value});\n\t\t} else {\n\t\t\tvalueQueue.push(value);\n\t\t}\n\n\t\tcancel();\n\t};\n\n\tfor (const event of events) {\n\t\taddListener(event, valueHandler);\n\t}\n\n\tfor (const rejectionEvent of options.rejectionEvents) {\n\t\taddListener(rejectionEvent, rejectHandler);\n\t}\n\n\tfor (const resolutionEvent of options.resolutionEvents) {\n\t\taddListener(resolutionEvent, resolveHandler);\n\t}\n\n\tif (options.signal) {\n\t\toptions.signal.addEventListener('abort', () => {\n\t\t\trejectHandler(options.signal.reason);\n\t\t}, {once: true});\n\t}\n\n\treturn {\n\t\t[Symbol.asyncIterator]() {\n\t\t\treturn this;\n\t\t},\n\t\tasync next() {\n\t\t\tif (valueQueue.length > 0) {\n\t\t\t\tconst value = valueQueue.shift();\n\t\t\t\treturn {\n\t\t\t\t\tdone: isDone && valueQueue.length === 0 && !isLimitReached,\n\t\t\t\t\tvalue,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (hasPendingError) {\n\t\t\t\thasPendingError = false;\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\tif (isDone) {\n\t\t\t\treturn {\n\t\t\t\t\tdone: true,\n\t\t\t\t\tvalue: undefined,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tnextQueue.push({resolve, reject});\n\t\t\t});\n\t\t},\n\t\tasync return(value) {\n\t\t\tcancel();\n\t\t\treturn {\n\t\t\t\tdone: isDone,\n\t\t\t\tvalue,\n\t\t\t};\n\t\t},\n\t};\n}\n\nexport {TimeoutError} from 'p-timeout';\n", "/**\n * Returns a `Uint8Array` of the requested size. Referenced memory will\n * be initialized to 0.\n */\nexport function alloc (size: number = 0): Uint8Array {\n return new Uint8Array(size)\n}\n\n/**\n * Where possible returns a Uint8Array of the requested size that references\n * uninitialized memory. Only use if you are certain you will immediately\n * overwrite every value in the returned `Uint8Array`.\n */\nexport function allocUnsafe (size: number = 0): Uint8Array {\n return new Uint8Array(size)\n}\n", "import { allocUnsafe } from '#alloc'\nimport { asUint8Array } from '#util/as-uint8array'\n\n/**\n * Returns a new Uint8Array created by concatenating the passed Uint8Arrays\n */\nexport function concat (arrays: Uint8Array[], length?: number): Uint8Array {\n if (length == null) {\n length = arrays.reduce((acc, curr) => acc + curr.length, 0)\n }\n\n const output = allocUnsafe(length)\n let offset = 0\n\n for (const arr of arrays) {\n output.set(arr, offset)\n offset += arr.length\n }\n\n return asUint8Array(output)\n}\n", "/**\n * Returns true if the two passed Uint8Arrays have the same content\n */\nexport function equals (a: Uint8Array, b: Uint8Array): boolean {\n if (a === b) {\n return true\n }\n\n if (a.byteLength !== b.byteLength) {\n return false\n }\n\n for (let i = 0; i < a.byteLength; i++) {\n if (a[i] !== b[i]) {\n return false\n }\n }\n\n return true\n}\n", "/**\n * @packageDocumentation\n *\n * A class that lets you do operations over a list of Uint8Arrays without\n * copying them.\n *\n * ```js\n * import { Uint8ArrayList } from 'uint8arraylist'\n *\n * const list = new Uint8ArrayList()\n * list.append(Uint8Array.from([0, 1, 2]))\n * list.append(Uint8Array.from([3, 4, 5]))\n *\n * list.subarray()\n * // -> Uint8Array([0, 1, 2, 3, 4, 5])\n *\n * list.consume(3)\n * list.subarray()\n * // -> Uint8Array([3, 4, 5])\n *\n * // you can also iterate over the list\n * for (const buf of list) {\n * // ..do something with `buf`\n * }\n *\n * list.subarray(0, 1)\n * // -> Uint8Array([0])\n * ```\n *\n * ## Converting Uint8ArrayLists to Uint8Arrays\n *\n * There are two ways to turn a `Uint8ArrayList` into a `Uint8Array` - `.slice` and `.subarray` and one way to turn a `Uint8ArrayList` into a `Uint8ArrayList` with different contents - `.sublist`.\n *\n * ### slice\n *\n * Slice follows the same semantics as [Uint8Array.slice](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice) in that it creates a new `Uint8Array` and copies bytes into it using an optional offset & length.\n *\n * ```js\n * const list = new Uint8ArrayList()\n * list.append(Uint8Array.from([0, 1, 2]))\n * list.append(Uint8Array.from([3, 4, 5]))\n *\n * list.slice(0, 1)\n * // -> Uint8Array([0])\n * ```\n *\n * ### subarray\n *\n * Subarray attempts to follow the same semantics as [Uint8Array.subarray](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/subarray) with one important different - this is a no-copy operation, unless the requested bytes span two internal buffers in which case it is a copy operation.\n *\n * ```js\n * const list = new Uint8ArrayList()\n * list.append(Uint8Array.from([0, 1, 2]))\n * list.append(Uint8Array.from([3, 4, 5]))\n *\n * list.subarray(0, 1)\n * // -> Uint8Array([0]) - no-copy\n *\n * list.subarray(2, 5)\n * // -> Uint8Array([2, 3, 4]) - copy\n * ```\n *\n * ### sublist\n *\n * Sublist creates and returns a new `Uint8ArrayList` that shares the underlying buffers with the original so is always a no-copy operation.\n *\n * ```js\n * const list = new Uint8ArrayList()\n * list.append(Uint8Array.from([0, 1, 2]))\n * list.append(Uint8Array.from([3, 4, 5]))\n *\n * list.sublist(0, 1)\n * // -> Uint8ArrayList([0]) - no-copy\n *\n * list.sublist(2, 5)\n * // -> Uint8ArrayList([2], [3, 4]) - no-copy\n * ```\n *\n * ## Inspiration\n *\n * Borrows liberally from [bl](https://www.npmjs.com/package/bl) but only uses native JS types.\n */\nimport { allocUnsafe, alloc } from 'uint8arrays/alloc'\nimport { concat } from 'uint8arrays/concat'\nimport { equals } from 'uint8arrays/equals'\n\nconst symbol = Symbol.for('@achingbrain/uint8arraylist')\n\nexport type Appendable = Uint8ArrayList | Uint8Array\n\nfunction findBufAndOffset (bufs: Uint8Array[], index: number): { buf: Uint8Array, index: number } {\n if (index == null || index < 0) {\n throw new RangeError('index is out of bounds')\n }\n\n let offset = 0\n\n for (const buf of bufs) {\n const bufEnd = offset + buf.byteLength\n\n if (index < bufEnd) {\n return {\n buf,\n index: index - offset\n }\n }\n\n offset = bufEnd\n }\n\n throw new RangeError('index is out of bounds')\n}\n\n/**\n * Check if object is a CID instance\n *\n * @example\n *\n * ```js\n * import { isUint8ArrayList, Uint8ArrayList } from 'uint8arraylist'\n *\n * isUint8ArrayList(true) // false\n * isUint8ArrayList([]) // false\n * isUint8ArrayList(new Uint8ArrayList()) // true\n * ```\n */\nexport function isUint8ArrayList (value: any): value is Uint8ArrayList {\n return Boolean(value?.[symbol])\n}\n\nexport class Uint8ArrayList implements Iterable<Uint8Array> {\n private bufs: Uint8Array[]\n public length: number\n public readonly [symbol] = true\n\n constructor (...data: Appendable[]) {\n this.bufs = []\n this.length = 0\n\n if (data.length > 0) {\n this.appendAll(data)\n }\n }\n\n * [Symbol.iterator] (): Iterator<Uint8Array> {\n yield * this.bufs\n }\n\n get byteLength (): number {\n return this.length\n }\n\n /**\n * Add one or more `bufs` to the end of this Uint8ArrayList\n */\n append (...bufs: Appendable[]): void {\n this.appendAll(bufs)\n }\n\n /**\n * Add all `bufs` to the end of this Uint8ArrayList\n */\n appendAll (bufs: Appendable[]): void {\n let length = 0\n\n for (const buf of bufs) {\n if (buf instanceof Uint8Array) {\n length += buf.byteLength\n this.bufs.push(buf)\n } else if (isUint8ArrayList(buf)) {\n length += buf.byteLength\n this.bufs.push(...buf.bufs)\n } else {\n throw new Error('Could not append value, must be an Uint8Array or a Uint8ArrayList')\n }\n }\n\n this.length += length\n }\n\n /**\n * Add one or more `bufs` to the start of this Uint8ArrayList\n */\n prepend (...bufs: Appendable[]): void {\n this.prependAll(bufs)\n }\n\n /**\n * Add all `bufs` to the start of this Uint8ArrayList\n */\n prependAll (bufs: Appendable[]): void {\n let length = 0\n\n for (const buf of bufs.reverse()) {\n if (buf instanceof Uint8Array) {\n length += buf.byteLength\n this.bufs.unshift(buf)\n } else if (isUint8ArrayList(buf)) {\n length += buf.byteLength\n this.bufs.unshift(...buf.bufs)\n } else {\n throw new Error('Could not prepend value, must be an Uint8Array or a Uint8ArrayList')\n }\n }\n\n this.length += length\n }\n\n /**\n * Read the value at `index`\n */\n get (index: number): number {\n const res = findBufAndOffset(this.bufs, index)\n\n return res.buf[res.index]\n }\n\n /**\n * Set the value at `index` to `value`\n */\n set (index: number, value: number): void {\n const res = findBufAndOffset(this.bufs, index)\n\n res.buf[res.index] = value\n }\n\n /**\n * Copy bytes from `buf` to the index specified by `offset`\n */\n write (buf: Appendable, offset: number = 0): void {\n if (buf instanceof Uint8Array) {\n for (let i = 0; i < buf.length; i++) {\n this.set(offset + i, buf[i])\n }\n } else if (isUint8ArrayList(buf)) {\n for (let i = 0; i < buf.length; i++) {\n this.set(offset + i, buf.get(i))\n }\n } else {\n throw new Error('Could not write value, must be an Uint8Array or a Uint8ArrayList')\n }\n }\n\n /**\n * Remove bytes from the front of the pool\n */\n consume (bytes: number): void {\n // first, normalize the argument, in accordance with how Buffer does it\n bytes = Math.trunc(bytes)\n\n // do nothing if not a positive number\n if (Number.isNaN(bytes) || bytes <= 0) {\n return\n }\n\n // if consuming all bytes, skip iterating\n if (bytes === this.byteLength) {\n this.bufs = []\n this.length = 0\n return\n }\n\n while (this.bufs.length > 0) {\n if (bytes >= this.bufs[0].byteLength) {\n bytes -= this.bufs[0].byteLength\n this.length -= this.bufs[0].byteLength\n this.bufs.shift()\n } else {\n this.bufs[0] = this.bufs[0].subarray(bytes)\n this.length -= bytes\n break\n }\n }\n }\n\n /**\n * Extracts a section of an array and returns a new array.\n *\n * This is a copy operation as it is with Uint8Arrays and Arrays\n * - note this is different to the behaviour of Node Buffers.\n */\n slice (beginInclusive?: number, endExclusive?: number): Uint8Array {\n const { bufs, length } = this._subList(beginInclusive, endExclusive)\n\n return concat(bufs, length)\n }\n\n /**\n * Returns a alloc from the given start and end element index.\n *\n * In the best case where the data extracted comes from a single Uint8Array\n * internally this is a no-copy operation otherwise it is a copy operation.\n */\n subarray (beginInclusive?: number, endExclusive?: number): Uint8Array {\n const { bufs, length } = this._subList(beginInclusive, endExclusive)\n\n if (bufs.length === 1) {\n return bufs[0]\n }\n\n return concat(bufs, length)\n }\n\n /**\n * Returns a allocList from the given start and end element index.\n *\n * This is a no-copy operation.\n */\n sublist (beginInclusive?: number, endExclusive?: number): Uint8ArrayList {\n const { bufs, length } = this._subList(beginInclusive, endExclusive)\n\n const list = new Uint8ArrayList()\n list.length = length\n // don't loop, just set the bufs\n list.bufs = [...bufs]\n\n return list\n }\n\n private _subList (beginInclusive?: number, endExclusive?: number): { bufs: Uint8Array[], length: number } {\n beginInclusive = beginInclusive ?? 0\n endExclusive = endExclusive ?? this.length\n\n if (beginInclusive < 0) {\n beginInclusive = this.length + beginInclusive\n }\n\n if (endExclusive < 0) {\n endExclusive = this.length + endExclusive\n }\n\n if (beginInclusive < 0 || endExclusive > this.length) {\n throw new RangeError('index is out of bounds')\n }\n\n if (beginInclusive === endExclusive) {\n return { bufs: [], length: 0 }\n }\n\n if (beginInclusive === 0 && endExclusive === this.length) {\n return { bufs: this.bufs, length: this.length }\n }\n\n const bufs: Uint8Array[] = []\n let offset = 0\n\n for (let i = 0; i < this.bufs.length; i++) {\n const buf = this.bufs[i]\n const bufStart = offset\n const bufEnd = bufStart + buf.byteLength\n\n // for next loop\n offset = bufEnd\n\n if (beginInclusive >= bufEnd) {\n // start after this buf\n continue\n }\n\n const sliceStartInBuf = beginInclusive >= bufStart && beginInclusive < bufEnd\n const sliceEndsInBuf = endExclusive > bufStart && endExclusive <= bufEnd\n\n if (sliceStartInBuf && sliceEndsInBuf) {\n // slice is wholly contained within this buffer\n if (beginInclusive === bufStart && endExclusive === bufEnd) {\n // requested whole buffer\n bufs.push(buf)\n break\n }\n\n // requested part of buffer\n const start = beginInclusive - bufStart\n bufs.push(buf.subarray(start, start + (endExclusive - beginInclusive)))\n break\n }\n\n if (sliceStartInBuf) {\n // slice starts in this buffer\n if (beginInclusive === 0) {\n // requested whole buffer\n bufs.push(buf)\n continue\n }\n\n // requested part of buffer\n bufs.push(buf.subarray(beginInclusive - bufStart))\n continue\n }\n\n if (sliceEndsInBuf) {\n if (endExclusive === bufEnd) {\n // requested whole buffer\n bufs.push(buf)\n break\n }\n\n // requested part of buffer\n bufs.push(buf.subarray(0, endExclusive - bufStart))\n break\n }\n\n // slice started before this buffer and ends after it\n bufs.push(buf)\n }\n\n return { bufs, length: endExclusive - beginInclusive }\n }\n\n indexOf (search: Uint8ArrayList | Uint8Array, offset: number = 0): number {\n if (!isUint8ArrayList(search) && !(search instanceof Uint8Array)) {\n throw new TypeError('The \"value\" argument must be a Uint8ArrayList or Uint8Array')\n }\n\n const needle = search instanceof Uint8Array ? search : search.subarray()\n\n offset = Number(offset ?? 0)\n\n if (isNaN(offset)) {\n offset = 0\n }\n\n if (offset < 0) {\n offset = this.length + offset\n }\n\n if (offset < 0) {\n offset = 0\n }\n\n if (search.length === 0) {\n return offset > this.length ? this.length : offset\n }\n\n // https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string-search_algorithm\n const M: number = needle.byteLength\n\n if (M === 0) {\n throw new TypeError('search must be at least 1 byte long')\n }\n\n // radix\n const radix: number = 256\n const rightmostPositions: Int32Array = new Int32Array(radix)\n\n // position of the rightmost occurrence of the byte c in the pattern\n for (let c: number = 0; c < radix; c++) {\n // -1 for bytes not in pattern\n rightmostPositions[c] = -1\n }\n\n for (let j = 0; j < M; j++) {\n // rightmost position for bytes in pattern\n rightmostPositions[needle[j]] = j\n }\n\n // Return offset of first match, -1 if no match\n const right = rightmostPositions\n const lastIndex = this.byteLength - needle.byteLength\n const lastPatIndex = needle.byteLength - 1\n let skip: number\n\n for (let i = offset; i <= lastIndex; i += skip) {\n skip = 0\n\n for (let j = lastPatIndex; j >= 0; j--) {\n const char: number = this.get(i + j)\n\n if (needle[j] !== char) {\n skip = Math.max(1, j - right[char])\n break\n }\n }\n\n if (skip === 0) {\n return i\n }\n }\n\n return -1\n }\n\n getInt8 (byteOffset: number): number {\n const buf = this.subarray(byteOffset, byteOffset + 1)\n const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength)\n\n return view.getInt8(0)\n }\n\n setInt8 (byteOffset: number, value: number): void {\n const buf = allocUnsafe(1)\n const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength)\n view.setInt8(0, value)\n\n this.write(buf, byteOffset)\n }\n\n getInt16 (byteOffset: number, littleEndian?: boolean): number {\n const buf = this.subarray(byteOffset, byteOffset + 2)\n const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength)\n\n return view.getInt16(0, littleEndian)\n }\n\n setInt16 (byteOffset: number, value: number, littleEndian?: boolean): void {\n const buf = alloc(2)\n const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength)\n view.setInt16(0, value, littleEndian)\n\n this.write(buf, byteOffset)\n }\n\n getInt32 (byteOffset: number, littleEndian?: boolean): number {\n const buf = this.subarray(byteOffset, byteOffset + 4)\n const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength)\n\n return view.getInt32(0, littleEndian)\n }\n\n setInt32 (byteOffset: number, value: number, littleEndian?: boolean): void {\n const buf = alloc(4)\n const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength)\n view.setInt32(0, value, littleEndian)\n\n this.write(buf, byteOffset)\n }\n\n getBigInt64 (byteOffset: number, littleEndian?: boolean): bigint {\n const buf = this.subarray(byteOffset, byteOffset + 8)\n const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength)\n\n return view.getBigInt64(0, littleEndian)\n }\n\n setBigInt64 (byteOffset: number, value: bigint, littleEndian?: boolean): void {\n const buf = alloc(8)\n const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength)\n view.setBigInt64(0, value, littleEndian)\n\n this.write(buf, byteOffset)\n }\n\n getUint8 (byteOffset: number): number {\n const buf = this.subarray(byteOffset, byteOffset + 1)\n const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength)\n\n return view.getUint8(0)\n }\n\n setUint8 (byteOffset: number, value: number): void {\n const buf = allocUnsafe(1)\n const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength)\n view.setUint8(0, value)\n\n this.write(buf, byteOffset)\n }\n\n getUint16 (byteOffset: number, littleEndian?: boolean): number {\n const buf = this.subarray(byteOffset, byteOffset + 2)\n const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength)\n\n return view.getUint16(0, littleEndian)\n }\n\n setUint16 (byteOffset: number, value: number, littleEndian?: boolean): void {\n const buf = alloc(2)\n const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength)\n view.setUint16(0, value, littleEndian)\n\n this.write(buf, byteOffset)\n }\n\n getUint32 (byteOffset: number, littleEndian?: boolean): number {\n const buf = this.subarray(byteOffset, byteOffset + 4)\n const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength)\n\n return view.getUint32(0, littleEndian)\n }\n\n setUint32 (byteOffset: number, value: number, littleEndian?: boolean): void {\n const buf = alloc(4)\n const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength)\n view.setUint32(0, value, littleEndian)\n\n this.write(buf, byteOffset)\n }\n\n getBigUint64 (byteOffset: number, littleEndian?: boolean): bigint {\n const buf = this.subarray(byteOffset, byteOffset + 8)\n const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength)\n\n return view.getBigUint64(0, littleEndian)\n }\n\n setBigUint64 (byteOffset: number, value: bigint, littleEndian?: boolean): void {\n const buf = alloc(8)\n const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength)\n view.setBigUint64(0, value, littleEndian)\n\n this.write(buf, byteOffset)\n }\n\n getFloat32 (byteOffset: number, littleEndian?: boolean): number {\n const buf = this.subarray(byteOffset, byteOffset + 4)\n const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength)\n\n return view.getFloat32(0, littleEndian)\n }\n\n setFloat32 (byteOffset: number, value: number, littleEndian?: boolean): void {\n const buf = alloc(4)\n const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength)\n view.setFloat32(0, value, littleEndian)\n\n this.write(buf, byteOffset)\n }\n\n getFloat64 (byteOffset: number, littleEndian?: boolean): number {\n const buf = this.subarray(byteOffset, byteOffset + 8)\n const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength)\n\n return view.getFloat64(0, littleEndian)\n }\n\n setFloat64 (byteOffset: number, value: number, littleEndian?: boolean): void {\n const buf = alloc(8)\n const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength)\n view.setFloat64(0, value, littleEndian)\n\n this.write(buf, byteOffset)\n }\n\n equals (other: any): other is Uint8ArrayList {\n if (other == null) {\n return false\n }\n\n if (!(other instanceof Uint8ArrayList)) {\n return false\n }\n\n if (other.bufs.length !== this.bufs.length) {\n return false\n }\n\n for (let i = 0; i < this.bufs.length; i++) {\n if (!equals(this.bufs[i], other.bufs[i])) {\n return false\n }\n }\n\n return true\n }\n\n /**\n * Create a Uint8ArrayList from a pre-existing list of Uint8Arrays. Use this\n * method if you know the total size of all the Uint8Arrays ahead of time.\n */\n static fromUint8Arrays (bufs: Uint8Array[], length?: number): Uint8ArrayList {\n const list = new Uint8ArrayList()\n list.bufs = bufs\n\n if (length == null) {\n length = bufs.reduce((acc, curr) => acc + curr.byteLength, 0)\n }\n\n list.length = length\n\n return list\n }\n}\n\n/*\nfunction indexOf (needle: Uint8Array, haystack: Uint8Array, offset = 0) {\n for (let i = offset; i < haystack.byteLength; i++) {\n for (let j = 0; j < needle.length; j++) {\n if (haystack[i + j] !== needle[j]) {\n break\n }\n\n if (j === needle.byteLength -1) {\n return i\n }\n }\n\n if (haystack.byteLength - i < needle.byteLength) {\n break\n }\n }\n\n return -1\n}\n*/\n", "export const PROTOCOL_NAME = '/perf/1.0.0'\nexport const WRITE_BLOCK_SIZE = 64 << 10\nexport const MAX_INBOUND_STREAMS = 1\nexport const MAX_OUTBOUND_STREAMS = 1\nexport const RUN_ON_LIMITED_CONNECTION = false\n", "import { pushable } from 'it-pushable'\nimport { pEvent } from 'p-event'\nimport { Uint8ArrayList } from 'uint8arraylist'\nimport { MAX_INBOUND_STREAMS, MAX_OUTBOUND_STREAMS, PROTOCOL_NAME, RUN_ON_LIMITED_CONNECTION, WRITE_BLOCK_SIZE } from './constants.js'\nimport type { PerfOptions, PerfOutput, PerfComponents, PerfInit, Perf as PerfInterface } from './index.js'\nimport type { Logger, Startable, Stream } from '@libp2p/interface'\nimport type { Multiaddr } from '@multiformats/multiaddr'\n\nexport class Perf implements Startable, PerfInterface {\n private readonly log: Logger\n public readonly protocol: string\n private readonly components: PerfComponents\n private started: boolean\n private readonly buf: ArrayBuffer\n private readonly writeBlockSize: number\n private readonly maxInboundStreams: number\n private readonly maxOutboundStreams: number\n private readonly runOnLimitedConnection: boolean\n\n constructor (components: PerfComponents, init: PerfInit = {}) {\n this.components = components\n this.log = components.logger.forComponent('libp2p:perf')\n this.started = false\n this.protocol = init.protocolName ?? PROTOCOL_NAME\n this.writeBlockSize = init.writeBlockSize ?? WRITE_BLOCK_SIZE\n this.buf = new ArrayBuffer(this.writeBlockSize)\n this.maxInboundStreams = init.maxInboundStreams ?? MAX_INBOUND_STREAMS\n this.maxOutboundStreams = init.maxOutboundStreams ?? MAX_OUTBOUND_STREAMS\n this.runOnLimitedConnection = init.runOnLimitedConnection ?? RUN_ON_LIMITED_CONNECTION\n this.handleMessage = this.handleMessage.bind(this)\n }\n\n readonly [Symbol.toStringTag] = '@libp2p/perf'\n\n async start (): Promise<void> {\n await this.components.registrar.handle(this.protocol, this.handleMessage, {\n maxInboundStreams: this.maxInboundStreams,\n maxOutboundStreams: this.maxOutboundStreams,\n runOnLimitedConnection: this.runOnLimitedConnection\n })\n this.started = true\n }\n\n async stop (): Promise<void> {\n await this.components.registrar.unhandle(this.protocol)\n this.started = false\n }\n\n isStarted (): boolean {\n return this.started\n }\n\n async handleMessage (stream: Stream): Promise<void> {\n try {\n const writeBlockSize = this.writeBlockSize\n\n let bytesToSendBack: number | undefined\n\n for await (const buf of stream) {\n if (bytesToSendBack == null) {\n const list = new Uint8ArrayList(buf)\n // downcast 64 to 52 bits to avoid bigint arithmetic performance penalty\n bytesToSendBack = Number(list.getBigUint64(0, false))\n }\n\n // Ingest all the data and wait for the read side to close\n }\n\n if (bytesToSendBack == null) {\n throw new Error('bytesToSendBack was not set')\n }\n\n const uint8Buf = new Uint8Array(this.buf, 0, this.buf.byteLength)\n\n while (bytesToSendBack > 0) {\n let toSend: number = writeBlockSize\n if (toSend > bytesToSendBack) {\n toSend = bytesToSendBack\n }\n\n bytesToSendBack = bytesToSendBack - toSend\n const buf = uint8Buf.subarray(0, toSend)\n\n const sendMore = stream.send(buf)\n\n if (!sendMore) {\n await pEvent(stream, 'drain', {\n rejectionEvents: [\n 'close'\n ]\n })\n }\n }\n\n await stream.close()\n } catch (err: any) {\n stream.abort(err)\n }\n }\n\n async * measurePerformance (ma: Multiaddr, sendBytes: number, receiveBytes: number, options: PerfOptions = {}): AsyncGenerator<PerfOutput> {\n const uint8Buf = new Uint8Array(this.buf)\n const writeBlockSize = this.writeBlockSize\n\n const initialStartTime = Date.now()\n let lastReportedTime = Date.now()\n const connection = await this.components.connectionManager.openConnection(ma, {\n ...options,\n force: options.reuseExistingConnection !== true\n })\n\n const log = connection.log.newScope('perf')\n\n log('opened connection after %d ms', Date.now() - lastReportedTime)\n lastReportedTime = Date.now()\n\n const stream = await connection.newStream(this.protocol, options)\n\n log('opened stream after %d ms', Date.now() - lastReportedTime)\n lastReportedTime = Date.now()\n\n let lastAmountOfBytesSent = 0\n let totalBytesSent = 0\n const uploadStart = Date.now()\n\n // tell the remote how many bytes we will send. Up cast to 64 bit number\n // as if we send as ui32 we limit total transfer size to 4GB\n const view = new DataView(this.buf)\n view.setBigUint64(0, BigInt(receiveBytes), false)\n\n log('sending %i bytes to %p', sendBytes, connection.remotePeer)\n\n try {\n const output = pushable<PerfOutput>({\n objectMode: true\n })\n\n Promise.resolve().then(async () => {\n const sendMore = stream.send(uint8Buf.subarray(0, 8))\n\n if (!sendMore) {\n await pEvent(stream, 'drain', {\n rejectionEvents: [\n 'close'\n ],\n signal: options.signal\n })\n }\n\n while (sendBytes > 0) {\n let toSend: number = writeBlockSize\n\n if (toSend > sendBytes) {\n toSend = sendBytes\n }\n\n const sendMore = stream.send(uint8Buf.subarray(0, toSend))\n\n if (!sendMore) {\n await pEvent(stream, 'drain', {\n rejectionEvents: [\n 'close'\n ],\n signal: options.signal\n })\n }\n\n sendBytes -= toSend\n\n if (Date.now() - lastReportedTime > 1000) {\n output.push({\n type: 'intermediary',\n timeSeconds: (Date.now() - lastReportedTime) / 1000,\n uploadBytes: lastAmountOfBytesSent,\n downloadBytes: 0\n })\n\n // record last reported time after `console.log` because it can\n // affect benchmark timings\n lastReportedTime = Date.now()\n lastAmountOfBytesSent = 0\n }\n\n lastAmountOfBytesSent += toSend\n totalBytesSent += toSend\n }\n\n output.end()\n })\n .catch(err => {\n output.end(err)\n })\n\n yield * output\n\n log('upload complete after %d ms', Date.now() - uploadStart)\n\n await stream.close(options)\n\n // Read the received bytes\n let lastAmountOfBytesReceived = 0\n lastReportedTime = Date.now()\n let totalBytesReceived = 0\n const downloadStart = Date.now()\n\n for await (const buf of stream) {\n if (Date.now() - lastReportedTime > 1000) {\n yield {\n type: 'intermediary',\n timeSeconds: (Date.now() - lastReportedTime) / 1000,\n uploadBytes: 0,\n downloadBytes: lastAmountOfBytesReceived\n }\n\n // record last reported time after `console.log` because it can\n // affect benchmark timings\n lastReportedTime = Date.now()\n lastAmountOfBytesReceived = 0\n }\n\n lastAmountOfBytesReceived += buf.byteLength\n totalBytesReceived += buf.byteLength\n }\n\n log('download complete after %d ms', Date.now() - downloadStart)\n\n if (totalBytesReceived !== receiveBytes) {\n throw new Error(`Expected to receive ${receiveBytes} bytes, but received ${totalBytesReceived}`)\n }\n\n yield {\n type: 'final',\n timeSeconds: (Date.now() - initialStartTime) / 1000,\n uploadBytes: totalBytesSent,\n downloadBytes: totalBytesReceived\n }\n\n log('performed %s to %p', this.protocol, connection.remotePeer)\n } catch (err: any) {\n log('error sending %d/%d bytes to %p: %s', totalBytesSent, sendBytes, connection.remotePeer, err)\n stream.abort(err)\n throw err\n }\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["index_exports", "__export", "perf", "pDefer", "deferred", "resolve", "reject", "FixedFIFO", "hwm", "data", "last", "FIFO", "options", "obj", "val", "prev", "next", "AbortError", "message", "code", "pushable", "options", "_pushable", "buffer", "next", "_pushable", "getNext", "options", "onEnd", "buffer", "FIFO", "pushable", "onNext", "ended", "drain", "pDefer", "waitNext", "resolve", "reject", "next", "err", "bufferNext", "bufferError", "push", "value", "end", "_return", "_throw", "signal", "cancel", "listener", "AbortError", "opts", "TimeoutError", "message", "AbortError", "getDOMException", "errorMessage", "getAbortedReason", "signal", "reason", "pTimeout", "promise", "options", "milliseconds", "fallback", "customTimers", "timer", "abortHandler", "cancelablePromise", "resolve", "reject", "timeoutError", "error", "normalizeEmitter", "emitter", "addListener", "removeListener", "pEventMultiple", "event", "options", "cancel", "returnValue", "resolve", "reject", "events", "items", "onItem", "arguments_", "value", "rejectHandler", "error", "rejectionEvent", "timeout", "pTimeout", "pEvent", "arrayPromise", "promise", "array", "alloc", "size", "allocUnsafe", "concat", "arrays", "length", "acc", "curr", "output", "allocUnsafe", "offset", "arr", "equals", "a", "b", "i", "symbol", "findBufAndOffset", "bufs", "index", "offset", "buf", "bufEnd", "isUint8ArrayList", "value", "Uint8ArrayList", "_Uint8ArrayList", "data", "length", "res", "i", "bytes", "beginInclusive", "endExclusive", "concat", "list", "bufStart", "sliceStartInBuf", "sliceEndsInBuf", "start", "search", "needle", "M", "radix", "rightmostPositions", "c", "j", "right", "lastIndex", "lastPatIndex", "skip", "char", "byteOffset", "allocUnsafe", "littleEndian", "alloc", "other", "equals", "acc", "curr", "PROTOCOL_NAME", "Perf", "components", "init", "PROTOCOL_NAME", "stream", "writeBlockSize", "bytesToSendBack", "buf", "list", "Uint8ArrayList", "uint8Buf", "toSend", "pEvent", "err", "ma", "sendBytes", "receiveBytes", "options", "initialStartTime", "lastReportedTime", "connection", "log", "lastAmountOfBytesSent", "totalBytesSent", "uploadStart", "output", "pushable", "lastAmountOfBytesReceived", "totalBytesReceived", "downloadStart", "perf", "init", "components", "Perf"]
7
7
  }
@@ -6,8 +6,8 @@
6
6
  * @example
7
7
  *
8
8
  * ```typescript
9
- * import { noise } from '@chainsafe/libp2p-noise'
10
- * import { yamux } from '@chainsafe/libp2p-yamux'
9
+ * import { noise } from '@libp2p/noise'
10
+ * import { yamux } from '@libp2p/yamux'
11
11
  * import { tcp } from '@libp2p/tcp'
12
12
  * import { createLibp2p, type Libp2p } from 'libp2p'
13
13
  * import { plaintext } from '@libp2p/plaintext'
package/dist/src/index.js CHANGED
@@ -6,8 +6,8 @@
6
6
  * @example
7
7
  *
8
8
  * ```typescript
9
- * import { noise } from '@chainsafe/libp2p-noise'
10
- * import { yamux } from '@chainsafe/libp2p-yamux'
9
+ * import { noise } from '@libp2p/noise'
10
+ * import { yamux } from '@libp2p/yamux'
11
11
  * import { tcp } from '@libp2p/tcp'
12
12
  * import { createLibp2p, type Libp2p } from 'libp2p'
13
13
  * import { plaintext } from '@libp2p/plaintext'
@@ -1,5 +1,5 @@
1
1
  import type { PerfOptions, PerfOutput, PerfComponents, PerfInit, Perf as PerfInterface } from './index.js';
2
- import type { Startable, IncomingStreamData } from '@libp2p/interface';
2
+ import type { Startable, Stream } from '@libp2p/interface';
3
3
  import type { Multiaddr } from '@multiformats/multiaddr';
4
4
  export declare class Perf implements Startable, PerfInterface {
5
5
  private readonly log;
@@ -16,7 +16,7 @@ export declare class Perf implements Startable, PerfInterface {
16
16
  start(): Promise<void>;
17
17
  stop(): Promise<void>;
18
18
  isStarted(): boolean;
19
- handleMessage(data: IncomingStreamData): Promise<void>;
19
+ handleMessage(stream: Stream): Promise<void>;
20
20
  measurePerformance(ma: Multiaddr, sendBytes: number, receiveBytes: number, options?: PerfOptions): AsyncGenerator<PerfOutput>;
21
21
  }
22
22
  //# sourceMappingURL=perf-service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"perf-service.d.ts","sourceRoot":"","sources":["../../src/perf-service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,IAAI,aAAa,EAAE,MAAM,YAAY,CAAA;AAC1G,OAAO,KAAK,EAAU,SAAS,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAC9E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAExD,qBAAa,IAAK,YAAW,SAAS,EAAE,aAAa;IACnD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,SAAgB,QAAQ,EAAE,MAAM,CAAA;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgB;IAC3C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IACjC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAQ;IACvC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAQ;IAC1C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAQ;IAC3C,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAS;gBAEnC,UAAU,EAAE,cAAc,EAAE,IAAI,GAAE,QAAa;IAY5D,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,kBAAiB;IAExC,KAAK,IAAK,OAAO,CAAC,IAAI,CAAC;IAavB,IAAI,IAAK,OAAO,CAAC,IAAI,CAAC;IAK5B,SAAS,IAAK,OAAO;IAIf,aAAa,CAAE,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAuCrD,kBAAkB,CAAE,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,cAAc,CAAC,UAAU,CAAC;CA6H3I"}
1
+ {"version":3,"file":"perf-service.d.ts","sourceRoot":"","sources":["../../src/perf-service.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,IAAI,aAAa,EAAE,MAAM,YAAY,CAAA;AAC1G,OAAO,KAAK,EAAU,SAAS,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAExD,qBAAa,IAAK,YAAW,SAAS,EAAE,aAAa;IACnD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,SAAgB,QAAQ,EAAE,MAAM,CAAA;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgB;IAC3C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IACjC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAQ;IACvC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAQ;IAC1C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAQ;IAC3C,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAS;gBAEnC,UAAU,EAAE,cAAc,EAAE,IAAI,GAAE,QAAa;IAa5D,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,kBAAiB;IAExC,KAAK,IAAK,OAAO,CAAC,IAAI,CAAC;IASvB,IAAI,IAAK,OAAO,CAAC,IAAI,CAAC;IAK5B,SAAS,IAAK,OAAO;IAIf,aAAa,CAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgD3C,kBAAkB,CAAE,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,cAAc,CAAC,UAAU,CAAC;CAgJ3I"}
@@ -1,4 +1,6 @@
1
1
  import { pushable } from 'it-pushable';
2
+ import { pEvent } from 'p-event';
3
+ import { Uint8ArrayList } from 'uint8arraylist';
2
4
  import { MAX_INBOUND_STREAMS, MAX_OUTBOUND_STREAMS, PROTOCOL_NAME, RUN_ON_LIMITED_CONNECTION, WRITE_BLOCK_SIZE } from './constants.js';
3
5
  export class Perf {
4
6
  log;
@@ -20,14 +22,11 @@ export class Perf {
20
22
  this.maxInboundStreams = init.maxInboundStreams ?? MAX_INBOUND_STREAMS;
21
23
  this.maxOutboundStreams = init.maxOutboundStreams ?? MAX_OUTBOUND_STREAMS;
22
24
  this.runOnLimitedConnection = init.runOnLimitedConnection ?? RUN_ON_LIMITED_CONNECTION;
25
+ this.handleMessage = this.handleMessage.bind(this);
23
26
  }
24
27
  [Symbol.toStringTag] = '@libp2p/perf';
25
28
  async start() {
26
- await this.components.registrar.handle(this.protocol, (data) => {
27
- void this.handleMessage(data).catch((err) => {
28
- this.log.error('error handling perf protocol message - %e', err);
29
- });
30
- }, {
29
+ await this.components.registrar.handle(this.protocol, this.handleMessage, {
31
30
  maxInboundStreams: this.maxInboundStreams,
32
31
  maxOutboundStreams: this.maxOutboundStreams,
33
32
  runOnLimitedConnection: this.runOnLimitedConnection
@@ -41,15 +40,15 @@ export class Perf {
41
40
  isStarted() {
42
41
  return this.started;
43
42
  }
44
- async handleMessage(data) {
45
- const { stream } = data;
43
+ async handleMessage(stream) {
46
44
  try {
47
45
  const writeBlockSize = this.writeBlockSize;
48
46
  let bytesToSendBack;
49
- for await (const buf of stream.source) {
47
+ for await (const buf of stream) {
50
48
  if (bytesToSendBack == null) {
49
+ const list = new Uint8ArrayList(buf);
51
50
  // downcast 64 to 52 bits to avoid bigint arithmetic performance penalty
52
- bytesToSendBack = Number(buf.getBigUint64(0, false));
51
+ bytesToSendBack = Number(list.getBigUint64(0, false));
53
52
  }
54
53
  // Ingest all the data and wait for the read side to close
55
54
  }
@@ -57,16 +56,23 @@ export class Perf {
57
56
  throw new Error('bytesToSendBack was not set');
58
57
  }
59
58
  const uint8Buf = new Uint8Array(this.buf, 0, this.buf.byteLength);
60
- await stream.sink(async function* () {
61
- while (bytesToSendBack > 0) {
62
- let toSend = writeBlockSize;
63
- if (toSend > bytesToSendBack) {
64
- toSend = bytesToSendBack;
65
- }
66
- bytesToSendBack = bytesToSendBack - toSend;
67
- yield uint8Buf.subarray(0, toSend);
59
+ while (bytesToSendBack > 0) {
60
+ let toSend = writeBlockSize;
61
+ if (toSend > bytesToSendBack) {
62
+ toSend = bytesToSendBack;
68
63
  }
69
- }());
64
+ bytesToSendBack = bytesToSendBack - toSend;
65
+ const buf = uint8Buf.subarray(0, toSend);
66
+ const sendMore = stream.send(buf);
67
+ if (!sendMore) {
68
+ await pEvent(stream, 'drain', {
69
+ rejectionEvents: [
70
+ 'close'
71
+ ]
72
+ });
73
+ }
74
+ }
75
+ await stream.close();
70
76
  }
71
77
  catch (err) {
72
78
  stream.abort(err);
@@ -99,14 +105,30 @@ export class Perf {
99
105
  const output = pushable({
100
106
  objectMode: true
101
107
  });
102
- stream.sink(async function* () {
103
- yield uint8Buf.subarray(0, 8);
108
+ Promise.resolve().then(async () => {
109
+ const sendMore = stream.send(uint8Buf.subarray(0, 8));
110
+ if (!sendMore) {
111
+ await pEvent(stream, 'drain', {
112
+ rejectionEvents: [
113
+ 'close'
114
+ ],
115
+ signal: options.signal
116
+ });
117
+ }
104
118
  while (sendBytes > 0) {
105
119
  let toSend = writeBlockSize;
106
120
  if (toSend > sendBytes) {
107
121
  toSend = sendBytes;
108
122
  }
109
- yield uint8Buf.subarray(0, toSend);
123
+ const sendMore = stream.send(uint8Buf.subarray(0, toSend));
124
+ if (!sendMore) {
125
+ await pEvent(stream, 'drain', {
126
+ rejectionEvents: [
127
+ 'close'
128
+ ],
129
+ signal: options.signal
130
+ });
131
+ }
110
132
  sendBytes -= toSend;
111
133
  if (Date.now() - lastReportedTime > 1000) {
112
134
  output.push({
@@ -124,18 +146,19 @@ export class Perf {
124
146
  totalBytesSent += toSend;
125
147
  }
126
148
  output.end();
127
- }())
149
+ })
128
150
  .catch(err => {
129
151
  output.end(err);
130
152
  });
131
153
  yield* output;
132
154
  log('upload complete after %d ms', Date.now() - uploadStart);
155
+ await stream.close(options);
133
156
  // Read the received bytes
134
157
  let lastAmountOfBytesReceived = 0;
135
158
  lastReportedTime = Date.now();
136
159
  let totalBytesReceived = 0;
137
160
  const downloadStart = Date.now();
138
- for await (const buf of stream.source) {
161
+ for await (const buf of stream) {
139
162
  if (Date.now() - lastReportedTime > 1000) {
140
163
  yield {
141
164
  type: 'intermediary',
@@ -162,7 +185,6 @@ export class Perf {
162
185
  downloadBytes: totalBytesReceived
163
186
  };
164
187
  log('performed %s to %p', this.protocol, connection.remotePeer);
165
- await stream.close();
166
188
  }
167
189
  catch (err) {
168
190
  log('error sending %d/%d bytes to %p: %s', totalBytesSent, sendBytes, connection.remotePeer, err);
@@ -1 +1 @@
1
- {"version":3,"file":"perf-service.js","sourceRoot":"","sources":["../../src/perf-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"perf-service.js","sourceRoot":"","sources":["../../src/perf-service.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@libp2p/perf",
3
- "version": "4.0.46-cf9aab5c8",
3
+ "version": "4.0.47-a02cb0461",
4
4
  "description": "Implementation of Perf Protocol",
5
5
  "author": "@maschad / @marcopolo",
6
6
  "license": "Apache-2.0 OR MIT",
@@ -45,17 +45,18 @@
45
45
  "doc-check": "aegir doc-check"
46
46
  },
47
47
  "dependencies": {
48
- "@libp2p/interface": "2.10.5-cf9aab5c8",
49
- "@libp2p/interface-internal": "2.3.18-cf9aab5c8",
50
- "@multiformats/multiaddr": "^12.4.4",
51
- "it-pushable": "^3.2.3"
48
+ "@libp2p/interface": "2.11.0-a02cb0461",
49
+ "@libp2p/interface-internal": "2.3.19-a02cb0461",
50
+ "@multiformats/multiaddr": "^12.5.1",
51
+ "it-pushable": "^3.2.3",
52
+ "p-event": "^6.0.1",
53
+ "uint8arraylist": "^2.4.8"
52
54
  },
53
55
  "devDependencies": {
54
- "@libp2p/interface-compliance-tests": "6.4.16-cf9aab5c8",
55
- "@libp2p/logger": "5.1.21-cf9aab5c8",
56
- "aegir": "^47.0.14",
57
- "it-last": "^3.0.8",
58
- "it-pair": "^2.0.6",
56
+ "@libp2p/logger": "5.2.0-a02cb0461",
57
+ "@libp2p/utils": "6.7.2-a02cb0461",
58
+ "aegir": "^47.0.21",
59
+ "it-last": "^3.0.9",
59
60
  "sinon-ts": "^2.0.0"
60
61
  },
61
62
  "sideEffects": false
package/src/index.ts CHANGED
@@ -6,8 +6,8 @@
6
6
  * @example
7
7
  *
8
8
  * ```typescript
9
- * import { noise } from '@chainsafe/libp2p-noise'
10
- * import { yamux } from '@chainsafe/libp2p-yamux'
9
+ * import { noise } from '@libp2p/noise'
10
+ * import { yamux } from '@libp2p/yamux'
11
11
  * import { tcp } from '@libp2p/tcp'
12
12
  * import { createLibp2p, type Libp2p } from 'libp2p'
13
13
  * import { plaintext } from '@libp2p/plaintext'
@@ -1,7 +1,9 @@
1
1
  import { pushable } from 'it-pushable'
2
+ import { pEvent } from 'p-event'
3
+ import { Uint8ArrayList } from 'uint8arraylist'
2
4
  import { MAX_INBOUND_STREAMS, MAX_OUTBOUND_STREAMS, PROTOCOL_NAME, RUN_ON_LIMITED_CONNECTION, WRITE_BLOCK_SIZE } from './constants.js'
3
5
  import type { PerfOptions, PerfOutput, PerfComponents, PerfInit, Perf as PerfInterface } from './index.js'
4
- import type { Logger, Startable, IncomingStreamData } from '@libp2p/interface'
6
+ import type { Logger, Startable, Stream } from '@libp2p/interface'
5
7
  import type { Multiaddr } from '@multiformats/multiaddr'
6
8
 
7
9
  export class Perf implements Startable, PerfInterface {
@@ -25,16 +27,13 @@ export class Perf implements Startable, PerfInterface {
25
27
  this.maxInboundStreams = init.maxInboundStreams ?? MAX_INBOUND_STREAMS
26
28
  this.maxOutboundStreams = init.maxOutboundStreams ?? MAX_OUTBOUND_STREAMS
27
29
  this.runOnLimitedConnection = init.runOnLimitedConnection ?? RUN_ON_LIMITED_CONNECTION
30
+ this.handleMessage = this.handleMessage.bind(this)
28
31
  }
29
32
 
30
33
  readonly [Symbol.toStringTag] = '@libp2p/perf'
31
34
 
32
35
  async start (): Promise<void> {
33
- await this.components.registrar.handle(this.protocol, (data: IncomingStreamData) => {
34
- void this.handleMessage(data).catch((err) => {
35
- this.log.error('error handling perf protocol message - %e', err)
36
- })
37
- }, {
36
+ await this.components.registrar.handle(this.protocol, this.handleMessage, {
38
37
  maxInboundStreams: this.maxInboundStreams,
39
38
  maxOutboundStreams: this.maxOutboundStreams,
40
39
  runOnLimitedConnection: this.runOnLimitedConnection
@@ -51,18 +50,17 @@ export class Perf implements Startable, PerfInterface {
51
50
  return this.started
52
51
  }
53
52
 
54
- async handleMessage (data: IncomingStreamData): Promise<void> {
55
- const { stream } = data
56
-
53
+ async handleMessage (stream: Stream): Promise<void> {
57
54
  try {
58
55
  const writeBlockSize = this.writeBlockSize
59
56
 
60
57
  let bytesToSendBack: number | undefined
61
58
 
62
- for await (const buf of stream.source) {
59
+ for await (const buf of stream) {
63
60
  if (bytesToSendBack == null) {
61
+ const list = new Uint8ArrayList(buf)
64
62
  // downcast 64 to 52 bits to avoid bigint arithmetic performance penalty
65
- bytesToSendBack = Number(buf.getBigUint64(0, false))
63
+ bytesToSendBack = Number(list.getBigUint64(0, false))
66
64
  }
67
65
 
68
66
  // Ingest all the data and wait for the read side to close
@@ -74,17 +72,27 @@ export class Perf implements Startable, PerfInterface {
74
72
 
75
73
  const uint8Buf = new Uint8Array(this.buf, 0, this.buf.byteLength)
76
74
 
77
- await stream.sink(async function * () {
78
- while (bytesToSendBack > 0) {
79
- let toSend: number = writeBlockSize
80
- if (toSend > bytesToSendBack) {
81
- toSend = bytesToSendBack
82
- }
75
+ while (bytesToSendBack > 0) {
76
+ let toSend: number = writeBlockSize
77
+ if (toSend > bytesToSendBack) {
78
+ toSend = bytesToSendBack
79
+ }
83
80
 
84
- bytesToSendBack = bytesToSendBack - toSend
85
- yield uint8Buf.subarray(0, toSend)
81
+ bytesToSendBack = bytesToSendBack - toSend
82
+ const buf = uint8Buf.subarray(0, toSend)
83
+
84
+ const sendMore = stream.send(buf)
85
+
86
+ if (!sendMore) {
87
+ await pEvent(stream, 'drain', {
88
+ rejectionEvents: [
89
+ 'close'
90
+ ]
91
+ })
86
92
  }
87
- }())
93
+ }
94
+
95
+ await stream.close()
88
96
  } catch (err: any) {
89
97
  stream.abort(err)
90
98
  }
@@ -127,8 +135,17 @@ export class Perf implements Startable, PerfInterface {
127
135
  objectMode: true
128
136
  })
129
137
 
130
- stream.sink(async function * () {
131
- yield uint8Buf.subarray(0, 8)
138
+ Promise.resolve().then(async () => {
139
+ const sendMore = stream.send(uint8Buf.subarray(0, 8))
140
+
141
+ if (!sendMore) {
142
+ await pEvent(stream, 'drain', {
143
+ rejectionEvents: [
144
+ 'close'
145
+ ],
146
+ signal: options.signal
147
+ })
148
+ }
132
149
 
133
150
  while (sendBytes > 0) {
134
151
  let toSend: number = writeBlockSize
@@ -137,7 +154,16 @@ export class Perf implements Startable, PerfInterface {
137
154
  toSend = sendBytes
138
155
  }
139
156
 
140
- yield uint8Buf.subarray(0, toSend)
157
+ const sendMore = stream.send(uint8Buf.subarray(0, toSend))
158
+
159
+ if (!sendMore) {
160
+ await pEvent(stream, 'drain', {
161
+ rejectionEvents: [
162
+ 'close'
163
+ ],
164
+ signal: options.signal
165
+ })
166
+ }
141
167
 
142
168
  sendBytes -= toSend
143
169
 
@@ -160,7 +186,7 @@ export class Perf implements Startable, PerfInterface {
160
186
  }
161
187
 
162
188
  output.end()
163
- }())
189
+ })
164
190
  .catch(err => {
165
191
  output.end(err)
166
192
  })
@@ -169,13 +195,15 @@ export class Perf implements Startable, PerfInterface {
169
195
 
170
196
  log('upload complete after %d ms', Date.now() - uploadStart)
171
197
 
198
+ await stream.close(options)
199
+
172
200
  // Read the received bytes
173
201
  let lastAmountOfBytesReceived = 0
174
202
  lastReportedTime = Date.now()
175
203
  let totalBytesReceived = 0
176
204
  const downloadStart = Date.now()
177
205
 
178
- for await (const buf of stream.source) {
206
+ for await (const buf of stream) {
179
207
  if (Date.now() - lastReportedTime > 1000) {
180
208
  yield {
181
209
  type: 'intermediary',
@@ -208,7 +236,6 @@ export class Perf implements Startable, PerfInterface {
208
236
  }
209
237
 
210
238
  log('performed %s to %p', this.protocol, connection.remotePeer)
211
- await stream.close()
212
239
  } catch (err: any) {
213
240
  log('error sending %d/%d bytes to %p: %s', totalBytesSent, sendBytes, connection.remotePeer, err)
214
241
  stream.abort(err)