UNPKG

reactive-channel

Version:

A simple yet powerful abstraction that enables communication between asynchronous tasks.

2 lines 2.85 kB
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`reactive-circular-queue`),t=require(`universal-stores`);var n=()=>void 0,r=class extends Error{constructor(){super(`channel full, cannot enqueue data`)}},i=class extends Error{constructor(){super(`channel closed`)}},a=class extends Error{constructor(){super(`channel has already too many pending recv`)}};function o(o){let{capacity:s=1024,maxConcurrentPendingRecv:c=1024}=o||{},l=(0,e.makeCircularQueue)(s),u=(0,e.makeCircularQueue)(s),d=(0,e.makeCircularQueue)(c),f=(0,t.makeStore)(!1),p=(0,t.makeDerivedStore)([f,l.availableSlots$],([e,t])=>e?0:t),m=(0,t.makeDerivedStore)([f,l.filledSlots$],([e,t])=>e?0:t),h=(0,t.makeDerivedStore)(p,e=>e>0),g=(0,t.makeDerivedStore)([m,d.full$],([e,t])=>e>0&&!t);async function _(e,t){if(f.content())throw new i;if(l.full$.content())throw new r;let a=n,o=n,s=new Promise((e,t)=>{a=e,o=t}),c;d.empty$.content()?(c={promise:s,resolveSend:a,rejectSend:o},l.enqueue(c),u.enqueue(e)):d.dequeue().resolveRecv({promise:s,resolveSend:a,rejectSend:o,value:e});try{if(!t?.signal)await s;else{let e=t.signal;e.throwIfAborted(),await Promise.race([s,new Promise((t,r)=>{e.addEventListener(`abort`,()=>{Promise.resolve().then(()=>r(e.reason)).catch(n)})})])}}catch(e){if(c){let e=l.indexOf(c);e!==-1&&(l.remove(e),u.remove(e))}throw e}}function v(e){if(f.content())throw new i;if(l.full$.content())throw new r;_(e).catch(n)}async function y(e){if(f.content())throw new i;let t;if(!l.empty$.content())t={...l.dequeue(),value:u.dequeue()};else{if(d.full$.content())throw new a;let r={resolveRecv:n,rejectRecv:n},i=new Promise((e,t)=>{r.resolveRecv=e,r.rejectRecv=t,d.enqueue(r)});try{if(!e?.signal)t=await i;else{let r=e.signal;r.throwIfAborted(),t=await Promise.race([i,new Promise((e,t)=>{r.addEventListener(`abort`,()=>{Promise.resolve().then(()=>t(r.reason)).catch(n)})})])}}catch(e){let t=d.indexOf(r);throw t!==-1&&d.remove(t),e}}return t.resolveSend(),t.value}async function*b(){for(;l.filledSlots$.content()>0;)yield await y()}function x(){if(f.content())return;f.set(!0);let e=new i;for(let t of d)t.rejectRecv(e);for(let t of l)t.rejectSend(e);u.clear()}return{buffer:u,tx:{send:v,sendWait:_,canWrite$:h,closed$:f,close:x,availableOutboxSlots$:p,capacity:s},rx:{pendingRecvPromises$:d.filledSlots$,recv:y,iter:b,[Symbol.asyncIterator]:b,canRead$:g,closed$:f,close:x,capacity:s,filledInboxSlots$:m}}}exports.ChannelClosedError=i,exports.ChannelFullError=r,exports.ChannelTooManyPendingRecvError=a,Object.defineProperty(exports,`NotEnoughAvailableSlotsQueueError`,{enumerable:!0,get:function(){return e.NotEnoughAvailableSlotsQueueError}}),Object.defineProperty(exports,`NotEnoughFilledSlotsQueueError`,{enumerable:!0,get:function(){return e.NotEnoughFilledSlotsQueueError}}),exports.makeChannel=o; //# sourceMappingURL=index.cjs.map