export class MessageStream{agent;options;state;constructor(t,e={}){this.agent=t,this.options={from:e.from,scope:e.scope,bufferSize:e.bufferSize??100,signal:e.signal,allowCleartext:e.allowCleartext??!1},this.state={buffer:[],pending:[],done:!1},this.options.signal&&this.options.signal.addEventListener("abort",()=>{this.close(new Error("Stream aborted"))});const s=t=>{this.handleEnvelope(t)},n=this.agent.getTransports()[0];n&&(n.onReceive(s),this.state.cleanup=()=>{})}async handleEnvelope(t){if(this.state.done)return;const e=await this.agent.receive(t,{allowCleartext:this.options.allowCleartext});if(!e.ok)return;const s=e.value;if(!(this.options.from&&s.sender!==this.options.from||this.options.scope&&s.scope!==this.options.scope))if(this.state.pending.length>0){this.state.pending.shift()({value:s,done:!1})}else this.state.buffer.length<this.options.bufferSize&&this.state.buffer.push(s)}close(t){if(!this.state.done){this.state.done=!0,this.state.error=t;for(const t of this.state.pending)t({value:void 0,done:!0});this.state.pending=[],this.state.cleanup&&this.state.cleanup()}}async next(){if(this.state.done)return{value:void 0,done:!0};if(this.options.signal?.aborted)return this.close(new Error("Stream aborted")),{value:void 0,done:!0};if(this.state.buffer.length>0){return{value:this.state.buffer.shift(),done:!1}}return new Promise(t=>{this.state.pending.push(t)})}async return(t){return this.close(),{value:void 0,done:!0}}async throw(t){return this.close(t instanceof Error?t:new Error(String(t))),{value:void 0,done:!0}}[Symbol.asyncIterator](){return this}get bufferedCount(){return this.state.buffer.length}get closed(){return this.state.done}get error(){return this.state.error}}export async function collectMessages(t,e={}){const s=[],n=new MessageStream(t,e);let o;e.timeout&&(o=setTimeout(()=>{n.return()},e.timeout));try{for await(const t of n)if(s.push(t),e.limit&&s.length>=e.limit)break}finally{o&&clearTimeout(o),n.closed||await n.return()}return s}export async function*mapStream(t,e){for await(const s of t)yield await e(s)}export async function*filterStream(t,e){for await(const s of t)await e(s)&&(yield s)}export async function*takeStream(t,e){let s=0;for await(const n of t){if(s>=e)break;yield n,s++}}export async function*mergeStreams(t){const e=t.map(t=>t[Symbol.asyncIterator]()),s=new Map;for(let t=0;t<e.length;t++)s.set(t,e[t].next());for(;s.size>0;){const t=Array.from(s.entries()),n=await Promise.race(t.map(async([t,e])=>({idx:t,result:await e})));s.delete(n.idx),n.result.done||(yield n.result.value,s.set(n.idx,e[n.idx].next()))}}export function installAsyncIterators(t){"subscribe"in t.prototype||(t.prototype.subscribe=function(t){return new MessageStream(this,t)})}