/* COPYRIGHT Esri - https://js.arcgis.com/5.0/LICENSE.txt */
import{createTask as e}from"./asyncUtils.js";import t from"./Collection.js";import{removeIfHandle as o,destroyHandle as s}from"./handleUtils.js";import{isAborted as r,createAbortError as n,ignoreAbortErrors as i}from"./promiseUtils.js";import{on as a}from"./reactiveUtils.js";function c(e,o,s){const r=s?.createCollection?.()??new t,n=!!s?.recycleItems?new d:null,i=(e,t=0)=>{if(!e?.length)return;const o=r.splice(t,e.length);n?n.processRemoved(e):o.forEach(m)},c=(e,t=0)=>{if(!e?.length)return;const s=[];for(const r of e){const e=n?.use(r);if(e)s.push(e);else{const e=o(r);n?.register(r,e),s.push(e)}}r.addMany(s,t)},l=a(e,"after-splice",({added:e,start:t,removed:o})=>{i(o,t),c(e,t)},{sync:!0,onListenerRemove:e=>i(e.items),onListenerAdd:e=>c(e.items)});return r.addHandles(l),r}class d{constructor(){this._originalToMapped=new Map,this._removedItemCandidates=new Set,this._garbageCollectionQueued=!1}processRemoved(e){if(!e?.length)return;const{_removedItemCandidates:t}=this;for(const o of e)this._getItem(o)?.markRemoved()&&(t.add(o),this._queueGarbageCollection())}use(e){const t=this._getItem(e);return t&&(t.removed=!1),t?.item}register(e,t){this._originalToMapped.set(e,new l(t))}_getItem(e){return this._originalToMapped.get(e)}_queueGarbageCollection(){this._garbageCollectionQueued||(this._garbageCollectionQueued=!0,queueMicrotask(()=>this._garbageCollectCandidates()))}_garbageCollectCandidates(){this._garbageCollectionQueued=!1;const{_removedItemCandidates:e}=this,t=Array.from(e);e.clear(),t.forEach(e=>this._garbageCollectIfRemoved(e))}_garbageCollectIfRemoved(e){const{_originalToMapped:t}=this,o=this._getItem(e);o?.removed&&(m(o.item),t.delete(e))}}class l{constructor(e){this.item=e,this.removed=!1}markRemoved(){return this.removed=!0,!0}}function m(e){"object"==typeof e&&e&&("destroy"in e&&"function"==typeof e.destroy?e.destroy():o(e))}function u(o,a,d){const l=new t,u=c(o,t=>e(async e=>{const o=await a(t,e);if(r(e))throw m(o),n();return o}),d),f=()=>null,g=async e=>{const t=await e.promise,o=u.indexOf(e);o<0||l.splice(o,1,t)};l.addMany(u.items.map(f));for(const e of u)i(g(e));const h=u.on("after-splice",({added:e,start:t,deleteCount:o})=>{const s=l.splice(t,o);for(const r of s)m(r);if(e?.length){l.addMany(e.map(f),t);for(const t of e)i(g(t))}});return l.addHandles([s(u),h]),l}export{c as mapCollection,u as mapCollectionAsync};
