UNPKG

async-states

Version:

Core of async-states

2 lines (1 loc) 13.1 kB
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).AsyncStates={})}(this,(function(t){"use strict";let e="undefined"!=typeof window?window:void 0,n=void 0===e||"Deno"in e,i=[];function s(t,e){return JSON.stringify({args:t,payload:e})}function a(t){return!!t&&r(t.then)}function r(t){return"function"==typeof t}function u(t){return{args:t.args,payload:t.payload}}const o=function(){let t=0;return function(){return t+=1,`async-state-${t}`}}();let c="error",l="pending",f="success",d="initial",p=()=>{},g=()=>Date.now(),h=Object.freeze,b=Array.isArray;function y(t,e){return Object.assign({},t,e)}let m=0;function v(t,e){if(!e)return;let{onError:n,onSuccess:i}=e;i&&t.status===f&&i(t),n&&t.status===c&&n(t)}function x(t,e){r(e)?e(t):"object"==typeof e&&e.status===t.status&&e.handler(t)}function k(t,e){let n=t.events;if(n&&n[e])switch(e){case"change":return void Object.values(n[e]).forEach((e=>{b(e)?e.forEach((e=>{x(t.actions.getState(),e)})):x(t.actions.getState(),e)}));case"dispose":return void Object.values(n[e]).forEach((t=>{b(t)?t.forEach((t=>t())):t()}));case"cache-change":return void Object.values(n[e]).forEach((e=>{b(e)?e.forEach((e=>e(t.cache))):e(t.cache)}))}}function S(t){return!!t.config.cacheConfig?.enabled}function C(t){let e=t;for(;e.parent;)e=e.parent;return e}function j(t,e,n){return(n??s)(e?.args||i,t)}function T(t,e){let n=C(t);return n.cache?.[e]}function w(t,e){let n=C(t);n.cache&&(delete n.cache[e],A(n))}function A(t){t.cache&&r(t.config.cacheConfig?.persist)&&t.config.cacheConfig.persist(t.cache),O(t)}function q(t){const{addedAt:e,deadline:n}=t;return e+n<g()}function O(t){k(t,"cache-change"),t.lanes&&Object.values(t.lanes).forEach((e=>{e.cache=t.cache,O(e)}))}function E(t){let e=C(t),{config:{cacheConfig:n}}=e,i=t.state,{props:a}=i;e.cache||(e.cache={});let u=(n?.hash||s)(a?.args,a?.payload);if(e.cache[u]?.state!==i){let s=I(i,n?.timeout),a=e.cache[u]={deadline:s,state:i,addedAt:g()};if(n?.auto&&Number.isFinite(s)){let n=setTimeout((()=>{let s=e.cache;if(!s)return;let a=s[u];a&&n===a.id&&(delete s[u],t.subscriptions&&Object.keys(t.subscriptions).length&&t.state===i&&t.actions.replay())}),s);a.id=n}n&&r(n.persist)&&n.persist(e.cache),O(e)}}function I(t,e){if(e&&!r(e))return e;let{data:n}=t,i=1/0;if(!e&&n&&((s=n.headers)&&r(s.get))){let t=P(n.headers);t&&t>0&&(i=t)}var s;return r(e)&&(i=e(t)),i}function P(t){let e=t.get("cache-control");if(e){let t=e.match(/max-age=(\d+)/);return t?parseInt(t[1],10):void 0}}function U(t){if(!S(t)||!r(t.config.cacheConfig?.load))return;if(t.parent){let e=C(t);return void(t.cache=e.cache)}let e=t.config.cacheConfig.load();e&&(a(e)?M(t,e):D(t,e))}function M(t,e){e.then((e=>{D(t,e)}))}function D(t,e){t.cache=e;const n=t.config.cacheConfig;r(n.onCacheLoad)&&n.onCacheLoad({cache:t.cache,source:t.actions})}function L(t,e){let n=r(e)?{cb:e}:e;if(!r(n.cb))return;t.subsIndex||(t.subsIndex=0),t.subscriptions||(t.subscriptions={}),t.subsIndex+=1;let i=n.key;function s(){delete t.subscriptions[i],t.config.resetStateOnDispose&&t.actions.dispose()}return void 0===i&&(i=`$${t.subsIndex}`),t.subscriptions[i]={props:n,cleanup:s},s}function R(t,e,n){t.events||(t.events={}),t.events[e]||(t.events[e]={});let i=t.events[e];t.eventsIndex||(t.eventsIndex=0);let s=++t.eventsIndex;return i[s]=n,function(){delete i[s]}}function V(t){t.subscriptions&&Object.values(t.subscriptions).forEach((e=>{e.props.cb(t.state)}))}let $=!1,F=!1,N=!1;function _(){let t=$;return $=!0,t}function z(){return F}function J(){let t=F;return F=!0,t}function K(t){F=t}function W(t){if(!t.queue)return null;let e=t.queue;for(;null!==e.next;)e=e.next;return e}function B(t,e){if(t.queue){let n=W(t);if(!n)return;n.next=e}else t.queue=e;X(t)}function G(t,e,n){B(t,{callbacks:n,data:e,kind:0,next:null})}function H(t,e,n=f,i){B(t,{callbacks:i,kind:1,data:{data:e,status:n},next:null})}function Q(t,e){B(t,{kind:2,data:e,next:null})}function X(t){if(!t.queue)return;let e=t.queue;if(e.id)return;let n=(t.config.keepPendingForMs||0)-(g()-t.state.timestamp);n>0?e.id=setTimeout((()=>Y(t)),n):Y(t)}function Y(t){if(!t.queue)return;let e=t.queue;t.queue=null;let n=N;for(N=!0;null!==e;){if(!(2!==e.kind&&e.data.status===l&&null!==e.next))switch(e.kind){case 0:{let{data:n,callbacks:i}=e,s={...n};s.timestamp=g(),h(s),tt(t,s,!1,i);break}case 1:{let{status:n,data:i}=e.data;it(t,i,n,e.callbacks);break}case 2:et=!0,it(t,e.data,f),et=!1}e=e.next}N=n,V(t)}function Z(t,e,n){function i(){let i=y(e);i.timestamp=g(),t.state=h(i),t.pendingUpdate=null,t.version+=1,k(t,"change"),n&&V(t)}let s=setTimeout(i,t.config.skipPendingDelayMs);t.pendingUpdate={callback:i,id:s}}function tt(t,e,n=!0,i){let{config:s}=t,a=e.status===l;a&&s.skipPendingStatus||(t.queue?G(t,e,i):!s.keepPendingForMs||t.state.status!==l||N?(t.pendingUpdate&&(clearTimeout(t.pendingUpdate.id),t.pendingUpdate=null),a&&s.skipPendingDelayMs&&r(setTimeout)&&s.skipPendingDelayMs>0?Z(t,e,n):(t.version+=1,t.state=e,v(e,i),k(t,"change"),t.state.status===f&&(t.lastSuccess=t.state,S(t)&&E(t)),n&&!N&&V(t))):G(t,e,i))}let et=!1;function nt(t,e){let n=et;et=!0,it(t,e),et=n}function it(t,e,n=f,i){if(t.queue){if(et){return Q(t,e),void(et=!1)}return void H(t,e,n,i)}let s=J();(t.state.status===l||r(t.currentAbort)&&!$)&&(t.actions.abort(),t.currentAbort=void 0);let a=e;if(r(e))if(et){a=e(t.lastSuccess.data??null)}else a=e(t.state);const o=u({args:[a],payload:y(t.payload)});let c={status:n,timestamp:g(),props:o,data:a};if(c.status===l){let e=t.state;e.status===l&&(e=e.prev),e&&(c.prev=e)}tt(t,c,!0,i),K(s)}function st(t){if(t.subscriptions&&Object.keys(t.subscriptions).length)return!1;let e=J();t.actions.abort(),t.queue&&(clearTimeout(t.queue.id),t.queue=null);let n=t.config.initialValue;r(n)&&(n=n(t.cache));let i={args:[n],payload:y(t.payload)};const s={status:d,timestamp:g(),data:n,props:i};return tt(t,s),t.lastSuccess=s,K(e),k(t,"dispose"),!0}function at(t,e,n,s){let a=t.actions.getState,u=s?.args||i,o=new AbortController;return{emit:function(n,i){if(e.cleared)return;if(!e.done)return;let a=_(),r=n,u=i;t.actions.setState(r,u,s),o=a,$=o;var o},args:u,abort:function(n){if(e.aborted||e.cleared)return;if(!e.done){e.aborted=!0;let n=t.state;n.status===l&&(n=n.prev),z()||tt(t,n,!0,s)}e.cleared=!0,o.abort(n),t.currentAbort=void 0},getState:a,payload:n,signal:o.signal,onAbort(t){r(t)&&o.signal.addEventListener("abort",(()=>{t(o.signal.reason)}))},isAborted:()=>e.aborted,get lastSuccess(){return t.lastSuccess}}}function rt(t,e,n,i,s,r){let o,d;try{if(d=t(e),n.aborted)return}catch(t){if(n.aborted)return;return void g(t)}if(a(d))return o=d,o=o.then(p,g),o.status=l,o;function p(t){return o&&(o.status="fulfilled",o.value=t),n.aborted||(n.done=!0,i(t,f,u(e),r)),t}function g(a){if(o&&(o.status="rejected",o.reason=a),!n.aborted)if(s?.enabled&&ut(n.index,s,a)){let u=ot(n.index,s,a);n.index+=1;let o=setTimeout((()=>{rt(t,e,n,i,s,r)}),u);e.onAbort((()=>{clearTimeout(o)}))}else n.done=!0,i(a,c,u(e),r)}p(d)}function ut(t,e,n){let{retry:i,maxAttempts:s}=e,a=!!s&&t<=s,u=void 0===i||!!i;return r(i)&&(u=i(t,n)),a&&u}function ot(t,e,n){let{backoff:i}=e;return r(i)?i(t,n):i||0}function ct(t,e){let n=t.config,i=Number(n.runEffectDurationMs)||0;if(!n.runEffect||0===i){return ht(t,Object.assign({},t.payload),e)}return ft(t,n.runEffect,i,e)}function lt(t,e,n){let i=null,s=setTimeout((function(){t.pendingTimeout=null;let e=Object.assign({},t.payload);i=ht(t,e,n)}),e);return t.pendingTimeout={at:g(),id:s},function(e){clearTimeout(s),t.pendingTimeout=null,r(i)&&i(e)}}function ft(t,e,n,i){switch(e){case"delay":case"debounce":if(t.pendingTimeout){g()<t.pendingTimeout.at+n&&clearTimeout(t.pendingTimeout.id)}return lt(t,n,i);case"throttle":if(t.pendingTimeout){if(g()<=t.pendingTimeout.at+n)return function(){};break}return lt(t,n,i)}return ht(t,Object.assign({},t.payload),i)}function dt(t){t.pendingUpdate&&(clearTimeout(t.pendingUpdate.id),t.pendingUpdate=null),t.actions.abort(),t.currentAbort=void 0}function pt(t,e){let n=e?.args??i,s=n[0],a=n[1];return t.actions.setState(s,a,e),p}function gt(t,e){let n=t.state,i=e.state;n!==i&&tt(t,i,!0)}function ht(t,e,n){if(t.promise=null,!t.fn)return pt(t,n);let i=J(),s=null!==t.pendingUpdate;if((t.state.status===l||s)&&dt(t),r(t.currentAbort)&&t.currentAbort(),S(t)){let i=t.config.cacheConfig,s=j(e,n,i?.hash),a=T(t,s);if(a&&!q(a))return void gt(t,a);a&&w(t,s)}let a={index:1,done:!1,cleared:!1,aborted:!1},o=at(t,a,e,n);t.latestRun={args:o.args,payload:o.payload},t.currentAbort=o.abort;let c=rt(t.fn,o,a,(function(e,n,i,s){let a=h({status:n,data:e,props:i,timestamp:g()});tt(t,a,!0,s)}),t.config.retryConfig,n);if(c){t.promise=c;let e=t.state;e.status===l&&(e=e.prev);let s=u(o),a={data:null,timestamp:g(),props:s,prev:e,status:l};return tt(t,a,!0,n),K(i),o.abort}return K(i),o.abort}let bt=new WeakMap,yt=vt(h({}));function mt(t){let e=new Map;return{ctx:t,payload:{},get:t=>e.get(t),remove:t=>e.delete(t),set(t,n){e.set(t,n)},getAll:()=>[...e.values()],terminate(){e=new Map}}}function vt(t){if(null===t)return yt;if("object"!=typeof t)throw new Error("createContext requires an object. Received "+String(typeof t));let e=bt.get(t);if(e)return e;let n=mt(t);return bt.set(t,n),n}function xt(t){if(null===t)return yt;let e=bt.get(t);if(!e)throw new Error("Context not found. Please make sure to call createContext before requestContext.");return e}const kt=n?function(t){return null}:function(t){if(!e)return null;let{key:n,config:i,ctx:s}=t,a=s?.name??null,r="__$$";null!==a&&(r=a);let u=e[r];if(!u)return null;let o=u[n];if(!o)return null;delete u[n],0===Object.keys(u).length&&delete e[r];let[c]=o,{status:l,props:f}=c;void 0===c.data&&(c.data=void 0,l!==d||null!==f.args[0]||i.initialValue||(f.args[0]=void 0));return o};function St(t){U(t);let e=kt(t);if(e){let[n,i,s]=e;if(t.state=n,t.payload=s,t.latestRun=i,t.state.status===f)t.lastSuccess=t.state;else{let e=t.config.initialValue,i=r(e)?e(t.cache):e,s={args:[i],payload:y(t.payload)};if(t.lastSuccess={status:d,data:i,timestamp:g(),props:s},n.status===l){let e=new Promise(((e,n)=>{t.res={res:e,rej:n}}));e.status=l,t.promise=e,n.prev=t.lastSuccess}}}else{let e=t.config.initialValue,n=r(e)?e(t.cache):e,i={args:[n],payload:y(t.payload)},s={status:d,data:n,timestamp:g(),props:i};t.state=s,t.lastSuccess=s}}class Ct{ctx;journal=null;actions;id;key;version=0;config;payload=null;cache=null;parent=null;lanes=null;state;queue=null;latestRun=null;lastSuccess;promise=null;res;currentAbort=null;fn=null;pendingUpdate=null;pendingTimeout=null;subsIndex=null;subscriptions=null;eventsIndex=null;events=null;global=null;constructor(t,e,n){let i=y(n);if(!1!==i.storeInContext){let i=xt(n?.context||null),s=i.get(t);if(s)return s.actions.patchConfig(n),s.actions.replaceProducer(e||null),s;this.ctx=i,i.set(t,this)}else this.ctx=null;this.key=t,this.id=++m,this.fn=e??null,this.config=i,this.actions=new jt(this),St(this)}}class jt{key;uniqueId;inst;constructor(t){this.inst=t,this.key=t.key,this.uniqueId=t.id}getState=()=>this.inst.state;replaceState=(t,e=!0,n)=>{tt(this.inst,t,e,n)};setState=(t,e=f,n)=>{it(this.inst,t,e,n)};setData=t=>{nt(this.inst,t)};on=(t,e)=>R(this.inst,t,e);run=(...t)=>this.inst.actions.runc({args:t});runp=(...t)=>{let e=this.inst;return new Promise((function(n){ct(e,{args:t,onError:n,onSuccess:n})}))};runc=t=>ct(this.inst,t);abort=(t=void 0)=>{let e=this.inst.currentAbort;r(e)&&e(t)};replay=()=>{let t=this.inst,e=t.latestRun;if(!e)return;let{args:n,payload:i}=e;return ht(t,i,{args:n})};invalidateCache=t=>{let e=this.inst;if(S(e)){const n=C(e);t?n.cache&&delete n.cache[t]:n.cache={},A(e)}};replaceCache=(t,e)=>{let n=this.inst;if(!S(n))return;const i=C(n);i.cache||(i.cache={}),i.cache[t]=e,O(i)};hasLane=t=>{let e=this.inst;return!!e.lanes&&!!e.lanes[t]};removeLane=t=>{let e=this.inst;return!(!e.lanes||!t)&&delete e.lanes[t]};getLane=t=>{if(!t)return this;let e=this.inst;e.lanes||(e.lanes={});let n=e.lanes[t];if(n)return n.actions;let i=e.fn,s=Object.assign({},e.config),a=new Ct(t,i,s);return a.parent=e,e.lanes[t]=a,a.actions};getVersion=()=>this.inst.version;getConfig=()=>this.inst.config;patchConfig=t=>{let e=this.inst.config;this.inst.config="function"==typeof t?{...e,...t(e)}:{...e,...t}};getPayload=()=>{let t=this.inst;return t.payload||(t.payload={}),t.payload};mergePayload=t=>{let e=this.inst;e.payload||(e.payload={}),e.payload=Object.assign(e.payload,t)};dispose=()=>st(this.inst);replaceProducer=t=>{this.inst.fn=t};subscribe=t=>L(this.inst,t);getAllLanes=()=>{let t=this.inst;return t.lanes?Object.values(t.lanes).map((t=>t.actions)):[]}}t.AsyncState=Ct,t.createContext=vt,t.createSource=function(t,e,n){let i;if("object"==typeof t){let{key:e,producer:n,config:s}=t;i=new Ct(e,n,s)}else i=new Ct(t,e,n);return i.actions},t.devtools=undefined,t.getSource=function(t,e){let n=xt(e||null);return n.get(t)?.actions},t.isSource=function(t){return t instanceof jt},t.nextKey=o,t.requestContext=xt,t.terminateContext=function(t){if(!t)return!1;let e=bt.get(t);return!!e&&(e.terminate(),bt.delete(t))}}));