UNPKG

9.99 kBJavaScriptView Raw
1import{createSelector}from"reselect";import{endsWith,startsWith,get,union,setWith,clone,mergeWith,isArray,isObjectLike,isPlainObject,map,transform,set,camelCase}from"lodash";import{denormalize,normalize}from"normalizr";const PREFIX="@API",REQUEST="REQUEST",SUCCESS="SUCCESS",FAILURE="FAILURE",CLEAR="CLEAR",REFRESH="REFRESH",successOf=e=>`${PREFIX}/${e}/${SUCCESS}`,requestOf=e=>`${PREFIX}/${e}/${REQUEST}`,failureOf=e=>`${PREFIX}/${e}/${FAILURE}`,clearOf=e=>`${PREFIX}/${e}/${CLEAR}`,refreshOf=e=>`${PREFIX}/${e}/${REFRESH}`;function isApi(e){const{key:t,type:n}=e;return t&&startsWith(n,PREFIX)}function isRequest(e){return isApi(e)&&endsWith(e.type,REQUEST)}function isSuccess(e){return isApi(e)&&endsWith(e.type,SUCCESS)}function isFailure(e){return isApi(e)&&endsWith(e.type,FAILURE)}function isClear(e){return isApi(e)&&endsWith(e.type,CLEAR)}function isRefresh(e){return isApi(e)&&endsWith(e.type,REFRESH)}const Apis=new Map;function registerSaga(e,t){Apis.set(e,t)}const initState={loading:!1,result:null,request:{},meta:{},total:0};function r(e=initState,t={}){const{payload:n={},error:r,meta:i={}}=t,{xTotalCount:a,result:o}=n,{append:u=!1}=i;return isRequest(t)?{...e,loading:!0,request:n,meta:i}:isSuccess(t)?{...e,loading:!1,result:u?union(o,e.result):o,total:a&&+a,meta:{...e.meta,...i}}:isFailure(t)?{...e,loading:!1,error:r,meta:{...e.meta,...i}}:isClear(t)?initState:e}const customizer=(e,t,n,r,i,a)=>{if(2===a.size&&isArray(t))return t};function entitiesReducer(e={},t){return t.payload&&t.payload.entities?mergeWith({},e,t.payload.entities,customizer):e}function apiReducer(e={},t){const{key:n}=t;if(isApi(t)){const i=Apis.get(n);return i?setWith({...e},i.reduxPath,r(get(e,i.reduxPath),t),clone):e}return e}const apiReducers={apis:apiReducer,entities:entitiesReducer};function createIteratee(e,t){return(n,r,i)=>set(n,e(i),isObjectLike(r)?t(r):r)}function createHumps(e){return function t(n){return isArray(n)?map(n,t):isPlainObject(n)?transform(n,createIteratee(e,t)):n}}const humps=createHumps(camelCase),camelCaseKey=e=>e.split(".").map(e=>camelCase(e)).join("."),entitiesSelector=e=>e.entities,makeStateSelector=e=>t=>get(t.apis,e)||initState,makeApiSelector=(e,t)=>{const n=camelCaseKey(e),r=makeStateSelector(n);return createSelector(r,entitiesSelector,(e,n)=>{const{result:r}=e;if(!r||!t)return e;const i=denormalize(r,t,n);return{...e,result:i}})};var createSymbol=function(e){return"@@redux-saga/"+e},CANCEL=createSymbol("CANCEL_PROMISE"),IO=createSymbol("IO"),MULTICAST=createSymbol("MULTICAST"),SELF_CANCELLATION=createSymbol("SELF_CANCELLATION"),undef=function(e){return null==e},notUndef=function(e){return null!=e},func=function(e){return"function"==typeof e},string=function(e){return"string"==typeof e},array=Array.isArray,pattern=function e(t){return t&&(string(t)||symbol(t)||func(t)||array(t)&&t.every(e))},channel=function(e){return e&&func(e.take)&&func(e.close)},stringableFunc=function(e){return func(e)&&e.hasOwnProperty("toString")},symbol=function(e){return!!e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype},multicast=function(e){return channel(e)&&e[MULTICAST]};function delayP(e,t){var n;void 0===t&&(t=!0);var r=new Promise(function(r){n=setTimeout(r,e,t)});return r[CANCEL]=function(){clearTimeout(n)},r}var konst=function(e){return function(){return e}},kTrue=konst(!0),noop=function(){},identity=function(e){return e},kThrow=function(e){throw e},kReturn=function(e){return{value:e,done:!0}};function makeIterator(e,t,n){void 0===t&&(t=kThrow),void 0===n&&(n="iterator");var r={meta:{name:n},next:e,throw:t,return:kReturn,isSagaIterator:!0};return"undefined"!=typeof Symbol&&(r[Symbol.iterator]=function(){return r}),r}var BUFFER_OVERFLOW="Channel's Buffer overflow!",ON_OVERFLOW_THROW=1,ON_OVERFLOW_DROP=2,ON_OVERFLOW_SLIDE=3,ON_OVERFLOW_EXPAND=4,zeroBuffer={isEmpty:kTrue,put:noop,take:noop};function ringBuffer(e,t){void 0===e&&(e=10);var n=[],r=0,i=0,a=0,o=function(t){n[i]=t,i=(i+1)%e,r++},u=function(){if(0!=r){var t=n[a];return n[a]=null,r--,a=(a+1)%e,t}},s=function(){for(var e=[];r;)e.push(u());return e};return{isEmpty:function(){return 0==r},put:function(u){var c;if(e>r)o(u);else switch(t){case ON_OVERFLOW_THROW:throw Error(BUFFER_OVERFLOW);case ON_OVERFLOW_SLIDE:n[i]=u,a=i=(i+1)%e;break;case ON_OVERFLOW_EXPAND:c=2*e,n=s(),r=n.length,i=n.length,a=0,n.length=c,e=c,o(u)}},take:u,flush:s}}var none=function(){return zeroBuffer},fixed=function(e){return ringBuffer(e,ON_OVERFLOW_THROW)},dropping=function(e){return ringBuffer(e,ON_OVERFLOW_DROP)},sliding=function(e){return ringBuffer(e,ON_OVERFLOW_SLIDE)},expanding=function(e){return ringBuffer(e,ON_OVERFLOW_EXPAND)},buffers=Object.freeze({none:none,fixed:fixed,dropping:dropping,sliding:sliding,expanding:expanding}),TAKE="TAKE",PUT="PUT",ALL="ALL",RACE="RACE",CALL="CALL",CPS="CPS",FORK="FORK",JOIN="JOIN",CANCEL$1="CANCEL",SELECT="SELECT",ACTION_CHANNEL="ACTION_CHANNEL",CANCELLED="CANCELLED",FLUSH="FLUSH",GET_CONTEXT="GET_CONTEXT",SET_CONTEXT="SET_CONTEXT",effectTypes=Object.freeze({TAKE:TAKE,PUT:PUT,ALL:ALL,RACE:RACE,CALL:CALL,CPS:CPS,FORK:FORK,JOIN:JOIN,CANCEL:CANCEL$1,SELECT:SELECT,ACTION_CHANNEL:ACTION_CHANNEL,CANCELLED:CANCELLED,FLUSH:FLUSH,GET_CONTEXT:GET_CONTEXT,SET_CONTEXT:SET_CONTEXT}),makeEffect=function(e,t){var n;return(n={})[IO]=!0,n.combinator=!1,n.type=e,n.payload=t,n};function take(e,t){return void 0===e&&(e="*"),pattern(e)?makeEffect(TAKE,{pattern:e}):multicast(e)&&notUndef(t)&&pattern(t)?makeEffect(TAKE,{channel:e,pattern:t}):channel(e)?makeEffect(TAKE,{channel:e}):void 0}function put(e,t){return undef(t)&&(t=e,e=void 0),makeEffect(PUT,{channel:e,action:t})}function all(e){var t=makeEffect(ALL,e);return t.combinator=!0,t}function getFnCallDescriptor(e,t){var n,r=null;return func(e)?n=e:(array(e)?(r=e[0],n=e[1]):(r=e.context,n=e.fn),r&&string(n)&&func(r[n])&&(n=r[n])),{context:r,fn:n,args:t}}function call(e){for(var t=arguments.length,n=[],r=1;t>r;r++)n[r-1]=arguments[r];return makeEffect(CALL,getFnCallDescriptor(e,n))}function fork(e){for(var t=arguments.length,n=[],r=1;t>r;r++)n[r-1]=arguments[r];return makeEffect(FORK,getFnCallDescriptor(e,n))}function cancel(e){return void 0===e&&(e=SELF_CANCELLATION),makeEffect(CANCEL$1,e)}function select(e){void 0===e&&(e=identity);for(var t=arguments.length,n=[],r=1;t>r;r++)n[r-1]=arguments[r];return makeEffect(SELECT,{selector:e,args:n})}var delay=call.bind(null,delayP),done=function(e){return{done:!0,value:e}},qEnd={};function safeName(e){return channel(e)?"channel":stringableFunc(e)?e+"":func(e)?e.name:e+""}function fsmIterator(e,t,n){var r,i,a,o=t;function u(t,n){if(o===qEnd)return done(t);if(n&&!i)throw o=qEnd,n;r&&r(t);var u=n?e[i](n):e[o]();return a=u.effect,r=u.stateUpdater,i=u.errorState,(o=u.nextState)===qEnd?done(t):a}return makeIterator(u,function(e){return u(null,e)},n)}function takeLatest(e,t){for(var n=arguments.length,r=[],i=2;n>i;i++)r[i-2]=arguments[i];var a,o,u={done:!1,value:take(e)},s=function(e){return{done:!1,value:fork.apply(void 0,[t].concat(r,[e]))}},c=function(e){return{done:!1,value:cancel(e)}},f=function(e){return a=e},l=function(e){return o=e};return fsmIterator({q1:function(){return{nextState:"q2",effect:u,stateUpdater:l}},q2:function(){return a?{nextState:"q3",effect:c(a)}:{nextState:"q1",effect:s(o),stateUpdater:f}},q3:function(){return{nextState:"q1",effect:s(o),stateUpdater:f}}},"q1","takeLatest("+safeName(e)+", "+t.name+")")}function takeLatest$1(e,t){for(var n=arguments.length,r=[],i=2;n>i;i++)r[i-2]=arguments[i];return fork.apply(void 0,[takeLatest,e,t].concat(r))}const sagaHooks={beforeRequest:null,afterRequest:null};function registerHooks(e={}){sagaHooks.beforeRequest=e.beforeRequest||null,sagaHooks.afterRequest=e.afterRequest||null}function*callAPI(e,t,n){if(!e)return;if(!t)return;const{payload:r}=t,i=Apis.get(e);if(!i)throw Error(`redux-api: api ${e} should be registered`);const a=i.endpoint;if(!a)throw Error(`redux-api: api ${e} should has endpoint`);const o=i.schema;if(sagaHooks.beforeRequest){if(!(yield call(sagaHooks.beforeRequest,e,t,i)))return}let u,s;try{u=(yield call(a,r))||{};const{body:t={},headers:i={}}=u,c=o?normalize(t,o):{result:t};yield put({type:successOf(e),payload:{...c,...humps(i)},key:e,meta:n})}catch(t){yield put({type:failureOf(e),error:t,key:e,meta:n}),s=t}sagaHooks.afterRequest&&(yield call(sagaHooks.afterRequest,e,t,i,u,s))}function*watchRequest(){const e={};for(;;){const t=yield take(isRequest),{meta:n={},key:r}=t;e[r]&&(yield cancel(e[r])),e[r]=yield fork(callAPI,r,t,n)}}function*watchRefresh(e){const{key:t}=e,n=Apis.get(t);if(!n)throw Error(`redux-api: api ${t} should be registered`);const r=makeStateSelector(n.reduxPath),i=yield select(r);yield put({type:requestOf(t),key:t,payload:i.request,meta:i.meta})}function*watchApis(){yield all([fork(watchRequest),takeLatest$1(isRefresh,watchRefresh)])}class Api{constructor(e,t,n,r){this._key=e,this._endpoint=t,this._schema=n,this._reduxPath=camelCaseKey(r||e)}get endpoint(){return this._endpoint}get key(){return this._key}get schema(){return this._schema}get reduxPath(){return this._reduxPath}get actions(){return{request:(e,t={})=>({type:requestOf(this.key),key:this.key,payload:e,meta:t}),clear:(e={})=>({type:clearOf(this.key),key:this.key,meta:e}),refresh:(e={})=>({type:refreshOf(this.key),key:this.key,meta:e})}}}function createApiActions(e,t={}){if(!e)throw Error("Api need a key!");if(!t.endpoint)throw Error("Api need an endpoint function");if(Apis.has(e))return Apis.get(e).actions;const n=new Api(e,t.endpoint,t.schema,t.reduxPath);return registerSaga(e,n),n.actions}function createApiSelector(e,t){return makeApiSelector(e,t)}function apiSelector(e,t){return console.warn("apiSelector function is deprecated, please use createApiSelector "),makeApiSelector(e,t)}export{createApiActions,createApiSelector,apiSelector,apiReducers,apiReducer,entitiesReducer,watchApis,registerHooks,isApi,isSuccess,isRequest,isFailure,successOf,failureOf,requestOf};
2//# sourceMappingURL=index.esm.js.map