/* COPYRIGHT Esri - https://js.arcgis.com/5.1.2/LICENSE.txt */
import{removeMaybe as e}from"./maybe.js";import{onAbort as s,onAbortOrThrow as t,isPromiseLike as r,createAbortError as i}from"./promiseUtils.js";import h from"./Queue.js";import c from"./ReactiveMap.js";import{schedule as n}from"./scheduling.js";import{signal as o}from"./signal.js";class l{constructor(e){this._schedule=null,this._deferreds=new c,this._controllers=new c,this._processingItems=new c,this._pausedSignal=o(!1),this.process=e.process,this.concurrency=e.concurrency,this.sharedConcurrency=e.sharedConcurrency??a,this._queue=new h(e.peeker)}destroy(){this.clear(),this._schedule=e(this._schedule)}get updating(){return this.running}get length(){return this._processingItems.size+this._queue.length}get running(){return!this._pausedSignal.value&&this._queue.length>0&&!this.full}get full(){return this._processingItems.size>=this.concurrency||this.sharedConcurrency.full}abort(e){const s=this._controllers.get(e);s?.abort()}clear(){this._queue.clear();const e=Array.from(this._controllers.values());this._controllers.clear(),e.forEach(e=>e.abort()),this.sharedConcurrency.current.value-=this._processingItems.size,this._processingItems.clear(),this._cancelNext()}forEach(e){this._deferreds.forEach((s,t)=>e(t))}_get(e){const s=this._deferreds.get(e);return s?.promise}pause(){this._pausedSignal.value||(this._pausedSignal.value=!0,this._cancelNext())}push(e,r){const h=this._get(e);if(h)return h;const c=new AbortController,n=Promise.withResolvers(),o=r?s(r,()=>c.abort()):null,l=()=>{const s=this._processingItems.get(e);s&&s.controller.abort(),_(),n.reject(i())},u=t(c.signal,l),_=()=>{u.remove(),o?.remove(),this._removeItem(e),this._queue.remove(e),this._scheduleNext()};return this._deferreds.set(e,n),this._controllers.set(e,c),n.promise.then(_,_),this._queue.push(e),this._scheduleNext(),n.promise}last(){return this._queue.last()}reset(){const e=Array.from(this._processingItems.values());this.sharedConcurrency.current.value-=this._processingItems.size,this._processingItems.clear();for(const s of e)this._queue.push(s.item),s.controller.abort();this._scheduleNext()}resume(){this._pausedSignal.value&&(this._pausedSignal.value=!1,this._scheduleNext())}takeAll(){const e=[];for(;this._queue.length;)e.push(this._queue.pop());return this.clear(),e}_removeItem(e){this._deferreds.delete(e),this._controllers.delete(e),this._processingItems.has(e)&&(this._processingItems.delete(e),this.sharedConcurrency.current.value-=1)}_scheduleNext(){this._pausedSignal.value||this._schedule||(this._schedule=n(()=>{this._schedule=null,this._next()}))}_next(){for(;this._queue.length>0&&this._processingItems.size<this.concurrency&&!this.sharedConcurrency.full;)this._process(this._queue.pop())}_cancelNext(){this._schedule&&(this._schedule.remove(),this._schedule=null)}_processResult(e,s){this._canProcessFulfillment(e)&&(this._scheduleNext(),this._deferreds.get(e.item).resolve(s))}_processError(e,s){this._canProcessFulfillment(e)&&(this._scheduleNext(),this._deferreds.get(e.item).reject(s))}_canProcessFulfillment(e){return!!this._deferreds.get(e.item)&&this._processingItems.get(e.item)===e}_process(e){if(null==e)return;let s;const t=new AbortController,i=new u(e,t);this._processingItems.set(e,i),this.sharedConcurrency.current.value+=1;try{s=this.process(e,t.signal)}catch(h){this._processError(i,h)}r(s)?(i.promise=s,s.then(e=>this._processResult(i,e),e=>this._processError(i,e))):this._processResult(i,s)}}class u{constructor(e,s){this.item=e,this.controller=s,this.promise=null}}class _{constructor(e){this.limit=e,this.current=o(0)}get full(){return this.current.value>=this.limit}}const a=new _(1/0);export{l as QueueProcessor,_ as SharedConcurrency};
