@mic-rexjs/usecases-react 2.3.2 → 2.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.min.js CHANGED
@@ -1,2 +1,2 @@
1
1
  /*! For license information please see index.min.js.LICENSE.txt */
2
- (()=>{var t={20:(t,e,n)=>{"use strict";var r=n(594),o=Symbol.for("react.element"),u=(Symbol.for("react.fragment"),Object.prototype.hasOwnProperty),a=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,i={key:!0,ref:!0,__self:!0,__source:!0};e.jsx=function(t,e,n){var r,l={},c=null,f=null;for(r in void 0!==n&&(c=""+n),void 0!==e.key&&(c=""+e.key),void 0!==e.ref&&(f=e.ref),e)u.call(e,r)&&!i.hasOwnProperty(r)&&(l[r]=e[r]);if(t&&t.defaultProps)for(r in e=t.defaultProps)void 0===l[r]&&(l[r]=e[r]);return{$$typeof:o,type:t,key:c,ref:f,props:l,_owner:a.current}}},848:(t,e,n)=>{"use strict";t.exports=n(20)},594:t=>{"use strict";t.exports=React}},e={};function n(r){var o=e[r];if(void 0!==o)return o.exports;var u=e[r]={exports:{}};return t[r](u,u.exports,n),u.exports}n.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var r in e)n.o(e,r)&&!n.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),n.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var r={};(()=>{"use strict";n.r(r),n.d(r,{UseCaseFragment:()=>A,useStatelessUseCase:()=>M,useUseCase:()=>x});var t=n(848),e=n(594),o=n.n(e);function u(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=new Array(e);n<e;n++)r[n]=t[n];return r}function a(t,e){if(t){if("string"==typeof t)return u(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?u(t,e):void 0}}function i(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){var n=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=n){var r,o,u,a,i=[],l=!0,c=!1;try{if(u=(n=n.call(t)).next,0===e){if(Object(n)!==n)return;l=!1}else for(;!(l=(r=u.call(n)).done)&&(i.push(r.value),i.length!==e);l=!0);}catch(t){c=!0,o=t}finally{try{if(!l&&null!=n.return&&(a=n.return(),Object(a)!==a))return}finally{if(c)throw o}}return i}}(t,e)||a(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}const l=ahooks;var c,f=function(t){return i((0,e.useState)((function(){return t})),1)[0]};function s(t){return s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},s(t)}function y(t){var e=function(t,e){if("object"!=s(t)||!t)return t;var n=t[Symbol.toPrimitive];if(void 0!==n){var r=n.call(t,"string");if("object"!=s(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(t)}(t);return"symbol"==s(e)?e:String(e)}!function(t){t[t.None=0]="None",t[t.RootEnabled=2]="RootEnabled",t[t.ContextEnabled=4]="ContextEnabled",t[t.EntityEnabled=8]="EntityEnabled",t[t.ContextRootEnabled=22]="ContextRootEnabled",t[t.EntityRootEnabled=62]="EntityRootEnabled",t[t.StatelessEnabled=72]="StatelessEnabled"}(c||(c={}));const d=usecases;var b=["watch","onChange","options"];function v(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function E(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?v(Object(n),!0).forEach((function(e){var r,o,u;r=t,o=e,u=n[e],(o=y(o))in r?Object.defineProperty(r,o,{value:u,enumerable:!0,configurable:!0,writable:!0}):r[o]=u})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):v(Object(n)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))}))}return t}var p,m=function(t){return i((0,e.useState)(t),1)[0]},h=new Map;!function(t){t[t.None=0]="None",t[t.Entity=2]="Entity",t[t.Mode=4]="Mode"}(p||(p={}));var S,g=(0,e.createContext)(null);!function(t){t[t.Normal=2]="Normal",t[t.Stateless=4]="Stateless"}(S||(S={}));var O=function(t,e){var n=t.length;if(n!==e.length)return!1;for(var r=0;r<n;r++)if(t[r]!==e[r])return!1;return!0},w=function(t,e){var n,r=e||{},o=r.onShouldCache,u=void 0===o?function(){return!0}:o,a=r.onCompare,i=void 0===a?function(t,e){return O(t,e)}:a;return function(){for(var e=u(),r=arguments.length,o=new Array(r),a=0;a<r;a++)o[a]=arguments[a];if(n&&e){var l=n,c=l.parameters,f=l.returnValue;if(i(c,o))return f}var s=t.apply(void 0,o);return e&&(n={parameters:o,returnValue:s}),s}},j=function(t,e,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0,o=(0,l.useLatest)(n),u=(0,l.useCreation)((function(){return w(o.current,{onCompare:function(){return!0}})}),[r,o]);return(0,l.useCreation)((function(){return(e&c.RootEnabled)!==c.RootEnabled&&t?t:u()}),[e,t,u])};function C(t){return function(t){if(Array.isArray(t))return u(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||a(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}var R=function(t,e){return"object"===s(t)&&null!==t&&Object.hasOwn(t,e)},P=function t(e,n,r,o){var u=arguments.length>4&&void 0!==arguments[4]?arguments[4]:[],a=void 0,l=i(r.match(/^([^.]+)\.(.+)$/)||[],3),c=l[1],f=void 0===c?r:c,s=l[2],y=void 0===s?"":s,d=R(e,f),b=R(n,f),v=[].concat(C(u),[f]);if(d||b){var E=d?e[f]:a,p=b?n[f]:a;if(y)return void t(E,p,y,o,v);if(E===p)return;o(E,p,v)}else if(!/^\d+^/.test(f))for(var m=Array.isArray(e)?e:[],h=Array.isArray(n)?n:[],S=m.length,g=h.length,O=Math.max(S,g),w=0;w<O;w++)t(m[w],h[w],r,o,[].concat(C(u),["".concat(w)]))},_=function(t,e,n){for(var r=function(){var t=i(u[o],2),r=t[0],a=t[1];P(n,e,r,(function(t,r,o){a({fieldPaths:o,newEntity:e,oldEntity:n,newValue:r,oldValue:t})}))},o=0,u=Object.entries(t);o<u.length;o++)r()},x=function(){for(var t,n=((t=(0,e.useRef)(!0)).current=!0,(0,e.useEffect)((function(){t.current=!1})),t),r=arguments.length,u=new Array(r),a=0;a<r;a++)u[a]=arguments[a];var y=function(t){return m((function(){var e=p.None,n=i(t,3),r=n[1],o=n[2];return"function"===s(r)&&(e|=p.Entity,"number"==typeof o&&(e|=p.Mode)),e}))}(u),v=function(t,e){var n=i(t,5),r=n[0],o=n[1],u=n[2],a=n[3],l=n[4],c=(e&p.Entity)===p.Entity,f=(e&p.Mode)===p.Mode;return c?f?[r,o,u,a||{},l||[]]:[r,o,S.Normal,u||{},a||[]]:[null,r,S.Normal,o||{},u||[]]}(u,y),C=i(v,5),R=C[0],P=C[1],x=C[2],A=C[3],M=C[4],N=f(P),I=N,T=N,k=function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:p.None,r=h,o=m((function(){if(r.has(t)){var o=r.get(t),u=o.value,a=o.times;return r.set(t,{value:u,times:a+1}),u}if((n&p.Entity)!==p.Entity)return g;var i=(0,e.createContext)(null);return r.set(t,{value:i,times:1}),i}));return(0,l.useUnmount)((function(){if(r.has(t)){var e=r.get(t),n=e.value,u=e.times;o===n&&(1!==u?r.set(t,{value:n,times:u-1}):r.delete(t))}})),o}(N,y),U=(0,e.useContext)(k),D=U,L=function(t,e,n){return(0,l.useCreation)((function(){var r=c.None,o=(n||{}).store;return(t&p.Entity)===p.Entity&&(r|=c.EntityRootEnabled),r|=n?c.ContextEnabled:c.RootEnabled,o&&(r|=c.EntityEnabled),(e&S.Stateless)===S.Stateless&&(r|=c.StatelessEnabled),r}),[t,n,e])}(y,x,U),F=function(t){var n=(0,e.useRef)(0),r=(0,e.useRef)([]),o=r.current,u=O(t,o);return r.current=t,n.current+=u?0:1,n.current}(M),V=(U||{}).reducers,$=void 0===V?null:V,z=(D||{}).store,B=i(function(t,n,r,o,u){var a=i((0,e.useState)(n),2),f=a[0],s=a[1],y=r?r.value:null,b=function(t,e,n,r){return(t&c.EntityRootEnabled)!==c.EntityRootEnabled?r:(t&c.StatelessEnabled)!==c.StatelessEnabled?e:"function"==typeof n?n():n}(t,f,n,y),v=(t&c.EntityEnabled)===c.EntityEnabled,E=(t&c.EntityRootEnabled)===c.EntityRootEnabled,p=j(r,t,(function(){if(!E)return new d.EntityStore(null);var e=(t&c.StatelessEnabled)===c.StatelessEnabled;return new d.EntityStore(b,{onChange:function(t){e||s(t)}})})),m=(0,l.useMemoizedFn)((function(){var t=o.onChange,e=o.watch,n=function(n,r){e&&_(e,n,r),null==t||t(n,r)};return p.watch(n),function(){p.unwatch(n)}}));return E&&(p.value=b),(0,e.useEffect)((function(){if(v)return m()}),[v,p,u,m]),(0,l.useCreation)((function(){return[b,p]}),[b,p])}(L,R,void 0===z?null:z,A,F),2),G=B[0],W=B[1],Y=j($,L,(function(){return(L&c.EntityEnabled)!==c.EntityEnabled?I(A):function(t,e,n){n.watch,n.onChange;var r=n.options,o=function(t,e){if(null==t)return{};var n,r,o=function(t,e){if(null==t)return{};var n,r,o={},u=Object.keys(t);for(r=0;r<u.length;r++)n=u[r],e.indexOf(n)>=0||(o[n]=t[n]);return o}(t,e);if(Object.getOwnPropertySymbols){var u=Object.getOwnPropertySymbols(t);for(r=0;r<u.length;r++)n=u[r],e.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(o[n]=t[n])}return o}(n,b);return(0,d.createEntityReducers)(e,t,E(E(E({},o),r),{},{onGenerate:function(t,e){return e}}))}(T,W,A)}),F),q=function(t,n,r,u){var a=r.value,i=(0,e.useMemo)((function(){return(t&c.EntityEnabled)===c.EntityEnabled?{store:r,reducers:u,statuses:t}:{reducers:u,statuses:t}}),[t,a,r,u]),s=(0,l.useLatest)(i);return f((function(t){var e=t.children,r=t.with,u=void 0===r?[]:r,a=n.Provider;return o().createElement(a,{value:s.current},u.reduceRight((function(t,e){return o().createElement(e,{},t)}),e))}))}(L,k,W,Y);return(0,l.useCreation)((function(){if((L&c.EntityEnabled)!==c.EntityEnabled)return Y;var t=(L&c.RootEnabled)===c.RootEnabled,e=function(t,e){var n={};return Object.entries(t).forEach((function(t){var r=i(t,2),o=r[0],u=r[1];n[o]=w(u,e)})),n}(Y,{onShouldCache:function(){return n.current}});return t?[G,e,q]:[G,e]}),[L,G,Y,q,n])},A=function(n){var r=n.usecase,o=n.watch,u=n.onChange;return x(r,{watch:o,onChange:u}),(0,t.jsx)(e.Fragment,{})},M=function(t,e,n,r){return x(t,e,S.Stateless,n,r)}})();var o=usecases="undefined"==typeof usecases?{}:usecases;for(var u in r)o[u]=r[u];r.__esModule&&Object.defineProperty(o,"__esModule",{value:!0})})();
2
+ (()=>{var t={20:(t,e,n)=>{"use strict";var r=n(594),o=Symbol.for("react.element"),u=(Symbol.for("react.fragment"),Object.prototype.hasOwnProperty),a=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,i={key:!0,ref:!0,__self:!0,__source:!0};e.jsx=function(t,e,n){var r,l={},c=null,f=null;for(r in void 0!==n&&(c=""+n),void 0!==e.key&&(c=""+e.key),void 0!==e.ref&&(f=e.ref),e)u.call(e,r)&&!i.hasOwnProperty(r)&&(l[r]=e[r]);if(t&&t.defaultProps)for(r in e=t.defaultProps)void 0===l[r]&&(l[r]=e[r]);return{$$typeof:o,type:t,key:c,ref:f,props:l,_owner:a.current}}},848:(t,e,n)=>{"use strict";t.exports=n(20)},594:t=>{"use strict";t.exports=React}},e={};function n(r){var o=e[r];if(void 0!==o)return o.exports;var u=e[r]={exports:{}};return t[r](u,u.exports,n),u.exports}n.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var r in e)n.o(e,r)&&!n.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),n.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var r={};(()=>{"use strict";n.r(r),n.d(r,{UseCaseFragment:()=>A,useStatelessUseCase:()=>M,useUseCase:()=>x});var t=n(848),e=n(594),o=n.n(e);function u(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=new Array(e);n<e;n++)r[n]=t[n];return r}function a(t,e){if(t){if("string"==typeof t)return u(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?u(t,e):void 0}}function i(t){return function(t){if(Array.isArray(t))return u(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||a(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function l(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){var n=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=n){var r,o,u,a,i=[],l=!0,c=!1;try{if(u=(n=n.call(t)).next,0===e){if(Object(n)!==n)return;l=!1}else for(;!(l=(r=u.call(n)).done)&&(i.push(r.value),i.length!==e);l=!0);}catch(t){c=!0,o=t}finally{try{if(!l&&null!=n.return&&(a=n.return(),Object(a)!==a))return}finally{if(c)throw o}}return i}}(t,e)||a(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}const c=ahooks;var f,s=function(t){return l((0,e.useState)((function(){return t})),1)[0]};function y(t){return y="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},y(t)}function d(t){var e=function(t,e){if("object"!=y(t)||!t)return t;var n=t[Symbol.toPrimitive];if(void 0!==n){var r=n.call(t,"string");if("object"!=y(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(t)}(t);return"symbol"==y(e)?e:String(e)}!function(t){t[t.None=0]="None",t[t.RootEnabled=2]="RootEnabled",t[t.ContextEnabled=4]="ContextEnabled",t[t.EntityEnabled=8]="EntityEnabled",t[t.ContextRootEnabled=22]="ContextRootEnabled",t[t.EntityRootEnabled=62]="EntityRootEnabled",t[t.StatelessEnabled=72]="StatelessEnabled"}(f||(f={}));const v=usecases;var b=["watch","onChange","options"];function E(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function p(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?E(Object(n),!0).forEach((function(e){var r,o,u;r=t,o=e,u=n[e],(o=d(o))in r?Object.defineProperty(r,o,{value:u,enumerable:!0,configurable:!0,writable:!0}):r[o]=u})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):E(Object(n)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))}))}return t}var m,h=function(t){return l((0,e.useState)(t),1)[0]},S=new Map;!function(t){t[t.None=0]="None",t[t.Entity=2]="Entity",t[t.Mode=4]="Mode"}(m||(m={}));var g,O=(0,e.createContext)(null);!function(t){t[t.Normal=2]="Normal",t[t.Stateless=4]="Stateless"}(g||(g={}));var w=function(t,e){var n=t.length;if(n!==e.length)return!1;for(var r=0;r<n;r++)if(t[r]!==e[r])return!1;return!0},j=function(t,e){var n,r=e||{},o=r.onShouldCache,u=void 0===o?function(){return!0}:o,a=r.onCompare,i=void 0===a?function(t,e){return w(t,e)}:a;return function(){for(var e=u(),r=arguments.length,o=new Array(r),a=0;a<r;a++)o[a]=arguments[a];if(n&&e){var l=n,c=l.parameters,f=l.returnValue;if(i(c,o))return f}var s=t.apply(void 0,o);return e&&(n={parameters:o,returnValue:s}),s}},C=function(t,e,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0,o=(0,c.useLatest)(n),u=(0,c.useCreation)((function(){return j(o.current,{onCompare:function(){return!0}})}),[r,o]);return(0,c.useCreation)((function(){return(e&f.RootEnabled)!==f.RootEnabled&&t?t:u()}),[e,t,u])},R=function(t,e){return"object"===y(t)&&null!==t&&Object.hasOwn(t,e)},P=function t(e,n,r,o){var u=arguments.length>4&&void 0!==arguments[4]?arguments[4]:[],a=void 0,c=l(r.match(/^([^.]+)\.(.+)$/)||[],3),f=c[1],s=void 0===f?r:f,y=c[2],d=void 0===y?"":y,v=R(e,s),b=R(n,s),E=[].concat(i(u),[s]);if(v||b){var p=v?e[s]:a,m=b?n[s]:a;if(d)return void t(p,m,d,o,E);if(p===m)return;o(p,m,E)}else if(!/^\d+^/.test(s))for(var h=Array.isArray(e)?e:[],S=Array.isArray(n)?n:[],g=h.length,O=S.length,w=Math.max(g,O),j=0;j<w;j++)t(h[j],S[j],r,o,[].concat(i(u),["".concat(j)]))},_=function(t,e,n){for(var r=function(){var t=l(u[o],2),r=t[0],a=t[1];P(n,e,r,(function(t,r,o){a({fieldPaths:o,newEntity:e,oldEntity:n,newValue:r,oldValue:t})}))},o=0,u=Object.entries(t);o<u.length;o++)r()},x=function(){for(var t,n=((t=(0,e.useRef)(!0)).current=!0,(0,e.useEffect)((function(){t.current=!1})),t),r=arguments.length,u=new Array(r),a=0;a<r;a++)u[a]=arguments[a];var d=function(t){return h((function(){var e=m.None,n=l(t,3),r=n[1],o=n[2];return"function"===y(r)&&(e|=m.Entity,"number"==typeof o&&(e|=m.Mode)),e}))}(u),E=function(t,e){var n=l(t,5),r=n[0],o=n[1],u=n[2],a=n[3],i=n[4],c=(e&m.Entity)===m.Entity,f=(e&m.Mode)===m.Mode;return c?f?[r,o,u,a||{},i||[]]:[r,o,g.Normal,u||{},a||[]]:[null,r,g.Normal,o||{},u||[]]}(u,d),R=l(E,5),P=R[0],x=R[1],A=R[2],M=R[3],N=R[4],I=s(x),k=I,T=I,L=function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:m.None,r=S,o=h((function(){if(r.has(t)){var o=r.get(t),u=o.value,a=o.times;return r.set(t,{value:u,times:a+1}),u}if((n&m.Entity)!==m.Entity)return O;var i=(0,e.createContext)(null);return r.set(t,{value:i,times:1}),i}));return(0,c.useUnmount)((function(){if(r.has(t)){var e=r.get(t),n=e.value,u=e.times;o===n&&(1!==u?r.set(t,{value:n,times:u-1}):r.delete(t))}})),o}(I,d),U=(0,e.useContext)(L),D=U,V=function(t,e,n){return(0,c.useCreation)((function(){var r=f.None,o=(n||{}).store;return(t&m.Entity)===m.Entity&&(r|=f.EntityRootEnabled),r|=n?f.ContextEnabled:f.RootEnabled,o&&(r|=f.EntityEnabled),(e&g.Stateless)===g.Stateless&&(r|=f.StatelessEnabled),r}),[t,n,e])}(d,A,U),$=(0,c.useLatest)(M),F=function(t){var n=(0,e.useRef)(0),r=(0,e.useRef)([]),o=r.current,u=w(t,o);return r.current=t,n.current+=u?0:1,n.current}(N),B=(U||{}).reducers,G=void 0===B?null:B,W=(D||{}).store,Y=l(function(t,n,r,o,u){var a=l((0,e.useState)(n),2),i=a[0],s=a[1],y=r?r.value:null,d=function(t,e,n,r){return(t&f.EntityRootEnabled)!==f.EntityRootEnabled?r:(t&f.StatelessEnabled)!==f.StatelessEnabled?e:"function"==typeof n?n():n}(t,i,n,y),b=(t&f.EntityEnabled)===f.EntityEnabled,E=(t&f.EntityRootEnabled)===f.EntityRootEnabled,p=(0,c.useLatest)(o),m=C(r,t,(function(){if(!E)return new v.EntityStore(null);var e=(t&f.StatelessEnabled)===f.StatelessEnabled;return new v.EntityStore(d,{onChange:function(t){e||s(t)}})}));return E&&(m.value=d),(0,e.useEffect)((function(){if(b){var t=function(t,e){var n=p.current,r=n.onChange,o=n.watch;o&&_(o,t,e),null==r||r(t,e)};return m.watch(t),function(){m.unwatch(t)}}}),[b,m,u,p]),(0,c.useCreation)((function(){return[d,m]}),[d,m])}(V,P,void 0===W?null:W,M,F),2),q=Y[0],z=Y[1],H=C(G,V,(function(){var t,e,n,r=(t=M,e=function(t,e){var n,r;return null===(n=(r=$.current)[t])||void 0===n?void 0:n.call.apply(n,[r].concat(i(e)))},n={},Object.keys(t).forEach((function(r){var o=t[r];n[r]="function"!=typeof o?o:function(){for(var t=arguments.length,n=new Array(t),o=0;o<t;o++)n[o]=arguments[o];return e(r,n)}})),n);return(V&f.EntityEnabled)!==f.EntityEnabled?k(r):function(t,e,n){n.watch,n.onChange;var r=n.options,o=function(t,e){if(null==t)return{};var n,r,o=function(t,e){if(null==t)return{};var n,r,o={},u=Object.keys(t);for(r=0;r<u.length;r++)n=u[r],e.indexOf(n)>=0||(o[n]=t[n]);return o}(t,e);if(Object.getOwnPropertySymbols){var u=Object.getOwnPropertySymbols(t);for(r=0;r<u.length;r++)n=u[r],e.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(o[n]=t[n])}return o}(n,b);return(0,v.createEntityReducers)(e,t,p(p(p({},o),r),{},{onGenerate:function(t,e){return e}}))}(T,z,r)}),F),J=function(t,n,r,u){var a=r.value,i=(0,e.useMemo)((function(){return(t&f.EntityEnabled)===f.EntityEnabled?{store:r,reducers:u,statuses:t}:{reducers:u,statuses:t}}),[t,a,r,u]),l=(0,c.useLatest)(i);return s((function(t){var e=t.children,r=t.with,u=void 0===r?[]:r,a=n.Provider;return o().createElement(a,{value:l.current},u.reduceRight((function(t,e){return o().createElement(e,{},t)}),e))}))}(V,L,z,H);return(0,c.useCreation)((function(){if((V&f.EntityEnabled)!==f.EntityEnabled)return H;var t=(V&f.RootEnabled)===f.RootEnabled,e=function(t,e){var n={};return Object.entries(t).forEach((function(t){var r=l(t,2),o=r[0],u=r[1];n[o]=j(u,e)})),n}(H,{onShouldCache:function(){return n.current}});return t?[q,e,J]:[q,e]}),[V,q,H,J,n])},A=function(n){var r=n.usecase,o=n.watch,u=n.onChange;return x(r,{watch:o,onChange:u}),(0,t.jsx)(e.Fragment,{})},M=function(t,e,n,r){return x(t,e,g.Stateless,n,r)}})();var o=usecases="undefined"==typeof usecases?{}:usecases;for(var u in r)o[u]=r[u];r.__esModule&&Object.defineProperty(o,"__esModule",{value:!0})})();
@@ -3,7 +3,7 @@ import { EntityStore } from '@mic-rexjs/usecases';
3
3
  import { UseCaseStatuses } from '../../enums/UseCaseStatuses';
4
4
  import { getRenderingEntity } from '../../methods/getRenderingEntity';
5
5
  import { useContextualItem } from '../useContextualItem';
6
- import { useCreation, useMemoizedFn } from 'ahooks';
6
+ import { useCreation, useLatest } from 'ahooks';
7
7
  import { triggerWatchers } from '../../methods/triggerWatchers';
8
8
  export const useEntity = (statuses, rootEntity, contextStore, options, depsKey) => {
9
9
  const [entityState, setEntityState] = useState(rootEntity);
@@ -11,6 +11,7 @@ export const useEntity = (statuses, rootEntity, contextStore, options, depsKey)
11
11
  const renderingEntity = getRenderingEntity(statuses, entityState, rootEntity, contextEntity);
12
12
  const entityEnabled = (statuses & UseCaseStatuses.EntityEnabled) === UseCaseStatuses.EntityEnabled;
13
13
  const entityRootEnabled = (statuses & UseCaseStatuses.EntityRootEnabled) === UseCaseStatuses.EntityRootEnabled;
14
+ const optionsRef = useLatest(options);
14
15
  const store = useContextualItem(contextStore, statuses, () => {
15
16
  if (!entityRootEnabled) {
16
17
  return new EntityStore(null);
@@ -25,9 +26,16 @@ export const useEntity = (statuses, rootEntity, contextStore, options, depsKey)
25
26
  },
26
27
  });
27
28
  });
28
- const rewatch = useMemoizedFn(() => {
29
- const { onChange, watch } = options;
29
+ if (entityRootEnabled) {
30
+ // 执行同步操作
31
+ store.value = renderingEntity;
32
+ }
33
+ useEffect(() => {
34
+ if (!entityEnabled) {
35
+ return;
36
+ }
30
37
  const onEntityChange = (newEntity, oldEntity) => {
38
+ const { onChange, watch } = optionsRef.current;
31
39
  if (watch) {
32
40
  triggerWatchers(watch, newEntity, oldEntity);
33
41
  }
@@ -37,17 +45,7 @@ export const useEntity = (statuses, rootEntity, contextStore, options, depsKey)
37
45
  return () => {
38
46
  store.unwatch(onEntityChange);
39
47
  };
40
- });
41
- if (entityRootEnabled) {
42
- // 执行同步操作
43
- store.value = renderingEntity;
44
- }
45
- useEffect(() => {
46
- if (!entityEnabled) {
47
- return;
48
- }
49
- return rewatch();
50
- }, [entityEnabled, store, depsKey, rewatch]);
48
+ }, [entityEnabled, store, depsKey, optionsRef]);
51
49
  return useCreation(() => {
52
50
  return [renderingEntity, store];
53
51
  }, [renderingEntity, store]);
@@ -1,4 +1,4 @@
1
- import { useCreation } from 'ahooks';
1
+ import { useCreation, useLatest } from 'ahooks';
2
2
  import { useContext } from 'react';
3
3
  import { useConstantFn } from '../useConstantFn';
4
4
  import { useProvider } from '../useProvider';
@@ -13,6 +13,7 @@ import { useEntity } from '../useEntity';
13
13
  import { useContextualItem } from '../useContextualItem';
14
14
  import { cacheCalls } from '../../methods/cacheCalls';
15
15
  import { useCompareDeps } from '../useCompareDeps';
16
+ import { captureCalls } from '../../methods/captureCalls';
16
17
  export const useUseCase = ((...args) => {
17
18
  const isRenderingRef = useIsRenderingRef();
18
19
  const argumentTypes = useArgumentTypes(args);
@@ -25,15 +26,19 @@ export const useUseCase = ((...args) => {
25
26
  const contextValue = useContext(context);
26
27
  const entityContextValue = contextValue;
27
28
  const statuses = useUseCaseStatuses(argumentTypes, mode, contextValue);
29
+ const optionsRef = useLatest(options);
28
30
  const depsKey = useCompareDeps(deps);
29
31
  const { reducers: contextReducers = null } = contextValue || {};
30
32
  const { store: contextStore = null } = entityContextValue || {};
31
33
  const [entity, store] = useEntity(statuses, unsafeEntity, contextStore, options, depsKey);
32
34
  const reducers = useContextualItem(contextReducers, statuses, () => {
35
+ const opts = captureCalls(options, (key, callArgs) => {
36
+ return optionsRef.current[key]?.(...callArgs);
37
+ });
33
38
  if ((statuses & UseCaseStatuses.EntityEnabled) !== UseCaseStatuses.EntityEnabled) {
34
- return usecase(options);
39
+ return usecase(opts);
35
40
  }
36
- const hookOptions = options;
41
+ const hookOptions = opts;
37
42
  return initEntityReducers(entityUseCase, store, hookOptions);
38
43
  }, depsKey);
39
44
  const Provider = useProvider(statuses, context, store, reducers);
@@ -19,18 +19,21 @@ const defaultFile = {
19
19
  };
20
20
  const fileUseCase = (options = {}) => {
21
21
  const entityReducers = objectUseCase();
22
- const { pathPrefix = '' } = options;
22
+ const { pathPrefix = '', onPathChange } = options;
23
23
  const init = function* (entity, newEntity = defaultFile) {
24
24
  yield () => {
25
25
  return newEntity;
26
26
  };
27
27
  };
28
28
  const setPath = function* (entity, path) {
29
+ const { path: oldPath } = entity;
30
+ const newPath = pathPrefix + path;
29
31
  yield {
30
32
  ...entity,
31
- path: pathPrefix + path,
33
+ path: newPath,
32
34
  ext: path.match(/\.[^.]+$/)?.[0] || '',
33
35
  };
36
+ onPathChange?.(newPath, oldPath);
34
37
  };
35
38
  const readFile = async function* (entity, path) {
36
39
  const size = 2000;
@@ -428,13 +431,12 @@ describe('useUseCase', () => {
428
431
  expect(onChange).toHaveBeenCalledTimes(1);
429
432
  expect(onChange).toHaveBeenLastCalledWith({ ...defaultFile, path: PATH_1, ext: EXT_1 }, defaultFile);
430
433
  });
431
- test('`options.onChange` should be updated after `deps` changed', () => {
434
+ test('`options.onChange` should always trigger the latest one', () => {
432
435
  const onChange1 = jest.fn();
433
436
  const onChange2 = jest.fn();
434
437
  let onChange = onChange1;
435
- let deps = [1];
436
438
  const { result } = renderHook(() => {
437
- return useUseCase(defaultFile, fileUseCase, { onChange }, deps);
439
+ return useUseCase(defaultFile, fileUseCase, { onChange }, []);
438
440
  });
439
441
  const { current: cores } = result;
440
442
  const [, reducers] = cores;
@@ -442,7 +444,6 @@ describe('useUseCase', () => {
442
444
  expect(onChange1).toHaveBeenCalledTimes(0);
443
445
  act(() => {
444
446
  setPath(PATH_1);
445
- deps = [2];
446
447
  onChange = onChange2;
447
448
  });
448
449
  expect(onChange2).toHaveBeenCalledTimes(0);
@@ -455,31 +456,6 @@ describe('useUseCase', () => {
455
456
  expect(onChange2).toHaveBeenCalledTimes(1);
456
457
  expect(onChange2).toHaveBeenLastCalledWith({ ...defaultFile, path: PATH_2, ext: EXT_2 }, { ...defaultFile, path: PATH_1, ext: EXT_1 });
457
458
  });
458
- test('`options.onChange` should not be updated if `deps` has not changed', () => {
459
- const onChange1 = jest.fn();
460
- const onChange2 = jest.fn();
461
- let onChange = onChange1;
462
- const { result } = renderHook(() => {
463
- return useUseCase(defaultFile, fileUseCase, { onChange }, []);
464
- });
465
- const { current: cores } = result;
466
- const [, reducers] = cores;
467
- const { setPath } = reducers;
468
- expect(onChange1).toHaveBeenCalledTimes(0);
469
- act(() => {
470
- setPath(PATH_1);
471
- onChange = onChange2;
472
- });
473
- expect(onChange2).toHaveBeenCalledTimes(0);
474
- expect(onChange1).toHaveBeenCalledTimes(1);
475
- expect(onChange1).toHaveBeenLastCalledWith({ ...defaultFile, path: PATH_1, ext: EXT_1 }, defaultFile);
476
- act(() => {
477
- setPath(PATH_2);
478
- });
479
- expect(onChange2).toHaveBeenCalledTimes(0);
480
- expect(onChange1).toHaveBeenCalledTimes(2);
481
- expect(onChange1).toHaveBeenLastCalledWith({ ...defaultFile, path: PATH_2, ext: EXT_2 }, { ...defaultFile, path: PATH_1, ext: EXT_1 });
482
- });
483
459
  test('`options.options` should override rest options', () => {
484
460
  const { result } = renderHook(() => {
485
461
  return useUseCase(defaultFile, fileUseCase, {
@@ -518,33 +494,6 @@ describe('useUseCase', () => {
518
494
  expect(onUpdate).toHaveBeenCalledTimes(0);
519
495
  expect(onDeepUpdate).toHaveBeenCalledTimes(0);
520
496
  });
521
- test('when `entity` change, it should trigger watchers', () => {
522
- const onPathChange = jest.fn();
523
- const onSizeChange = jest.fn();
524
- const { result } = renderHook(() => {
525
- return useUseCase(defaultFile, fileUseCase, {
526
- watch: {
527
- path: onPathChange,
528
- size: onSizeChange,
529
- },
530
- });
531
- });
532
- const { current: cores } = result;
533
- const [, { setPath }] = cores;
534
- expect(onPathChange).toHaveBeenCalledTimes(0);
535
- act(() => {
536
- setPath(PATH_1);
537
- });
538
- expect(onPathChange).toHaveBeenCalledTimes(1);
539
- expect(onSizeChange).toHaveBeenCalledTimes(0);
540
- expect(onPathChange).toHaveBeenLastCalledWith({
541
- fieldPaths: ['path'],
542
- newEntity: { ...defaultFile, path: PATH_1, ext: EXT_1 },
543
- oldEntity: defaultFile,
544
- newValue: PATH_1,
545
- oldValue: '',
546
- });
547
- });
548
497
  test('when `deps` has changed, it should trigger update', () => {
549
498
  const onUpdate = jest.fn();
550
499
  const onDeepUpdate = jest.fn();
@@ -589,49 +538,57 @@ describe('useUseCase', () => {
589
538
  expect(onUpdate).toHaveBeenCalledTimes(0);
590
539
  expect(onDeepUpdate).toHaveBeenCalledTimes(0);
591
540
  });
592
- test('`options.watch` should be updated after `deps` changed', () => {
541
+ test(`should call latest functions of usecase options even deps has not change`, () => {
593
542
  const onPathChange1 = jest.fn();
594
543
  const onPathChange2 = jest.fn();
595
544
  let onPathChange = onPathChange1;
596
- let deps = [1];
545
+ const { result } = renderHook(() => {
546
+ return useUseCase(defaultFile, fileUseCase, { onPathChange });
547
+ });
548
+ const { current: context } = result;
549
+ const [, { setPath }] = context;
550
+ act(() => {
551
+ setPath(PATH_1);
552
+ onPathChange = onPathChange2;
553
+ });
554
+ expect(onPathChange1).toHaveBeenCalledTimes(1);
555
+ expect(onPathChange2).toHaveBeenCalledTimes(0);
556
+ expect(onPathChange1).toHaveBeenLastCalledWith(PATH_1, '');
557
+ act(() => {
558
+ setPath(PATH_2);
559
+ });
560
+ expect(onPathChange1).toHaveBeenCalledTimes(1);
561
+ expect(onPathChange2).toHaveBeenCalledTimes(1);
562
+ expect(onPathChange2).toHaveBeenLastCalledWith(PATH_2, PATH_1);
563
+ });
564
+ test('`options.watch` should be trigger after entity changed', () => {
565
+ const onPathChange = jest.fn();
566
+ const onSizeChange = jest.fn();
597
567
  const { result } = renderHook(() => {
598
568
  return useUseCase(defaultFile, fileUseCase, {
599
569
  watch: {
600
570
  path: onPathChange,
571
+ size: onSizeChange,
601
572
  },
602
- }, deps);
573
+ });
603
574
  });
604
575
  const { current: cores } = result;
605
- const [, { setPath, setEntity }] = cores;
606
- expect(onPathChange1).toHaveBeenCalledTimes(0);
576
+ const [, { setPath }] = cores;
577
+ expect(onPathChange).toHaveBeenCalledTimes(0);
607
578
  act(() => {
608
579
  setPath(PATH_1);
609
- setEntity({ size: 5000 });
610
- deps = [2];
611
- onPathChange = onPathChange2;
612
580
  });
613
- expect(onPathChange1).toHaveBeenCalledTimes(1);
614
- expect(onPathChange1).toHaveBeenLastCalledWith({
581
+ expect(onPathChange).toHaveBeenCalledTimes(1);
582
+ expect(onSizeChange).toHaveBeenCalledTimes(0);
583
+ expect(onPathChange).toHaveBeenLastCalledWith({
615
584
  fieldPaths: ['path'],
616
585
  newEntity: { ...defaultFile, path: PATH_1, ext: EXT_1 },
617
586
  oldEntity: defaultFile,
618
587
  newValue: PATH_1,
619
588
  oldValue: '',
620
589
  });
621
- act(() => {
622
- setPath('');
623
- });
624
- expect(onPathChange1).toHaveBeenCalledTimes(1);
625
- expect(onPathChange2).toHaveBeenCalledTimes(1);
626
- expect(onPathChange2).toHaveBeenLastCalledWith({
627
- fieldPaths: ['path'],
628
- newEntity: { ...defaultFile, size: 5000 },
629
- oldEntity: { ...defaultFile, path: PATH_1, ext: EXT_1, size: 5000 },
630
- newValue: '',
631
- oldValue: PATH_1,
632
- });
633
590
  });
634
- test('`options.watch` should not be updated if `deps` has not changed', () => {
591
+ test('`options.watch` should trigger the latest one', () => {
635
592
  const onPathChange1 = jest.fn();
636
593
  const onPathChange2 = jest.fn();
637
594
  let onPathChange = onPathChange1;
@@ -640,7 +597,7 @@ describe('useUseCase', () => {
640
597
  watch: {
641
598
  path: onPathChange,
642
599
  },
643
- }, []);
600
+ });
644
601
  });
645
602
  const { current: cores } = result;
646
603
  const [, { setPath, setEntity }] = cores;
@@ -661,9 +618,9 @@ describe('useUseCase', () => {
661
618
  act(() => {
662
619
  setPath('');
663
620
  });
664
- expect(onPathChange2).toHaveBeenCalledTimes(0);
665
- expect(onPathChange1).toHaveBeenCalledTimes(2);
666
- expect(onPathChange1).toHaveBeenLastCalledWith({
621
+ expect(onPathChange1).toHaveBeenCalledTimes(1);
622
+ expect(onPathChange2).toHaveBeenCalledTimes(1);
623
+ expect(onPathChange2).toHaveBeenLastCalledWith({
667
624
  fieldPaths: ['path'],
668
625
  newEntity: { ...defaultFile, size: 5000 },
669
626
  oldEntity: { ...defaultFile, path: PATH_1, ext: EXT_1, size: 5000 },
@@ -1319,99 +1276,6 @@ describe('useUseCase', () => {
1319
1276
  fireEvent.click(screen.getByText(updateButtonText));
1320
1277
  expect(addReducer).toHaveBeenCalledTimes(3);
1321
1278
  });
1322
- test.each([UseCaseModes.Normal, UseCaseModes.Stateless])('[mode=%s]: `options.watch` should be updated in child element after `deps` changed', (mode) => {
1323
- const onFirstExtChange = jest.fn();
1324
- const onSecondExtChange = jest.fn();
1325
- let onExtChange = onFirstExtChange;
1326
- let deps = [1];
1327
- const firstButtonText = 'first button';
1328
- const secondButtonText = 'second button';
1329
- const A = () => {
1330
- useUseCase(fileUseCase, {
1331
- watch: {
1332
- ext: onExtChange,
1333
- },
1334
- }, deps);
1335
- return _jsx(Fragment, {});
1336
- };
1337
- const B = () => {
1338
- const [file, setFile] = useState(defaultFile);
1339
- const [, { setPath }, Provider] = useUseCase(file, fileUseCase, mode, {
1340
- onChange(newFile) {
1341
- if ((mode & UseCaseModes.Stateless) !== UseCaseModes.Stateless) {
1342
- return;
1343
- }
1344
- // `stateless` 不会保存状态,所以需要手动保存
1345
- setFile(newFile);
1346
- },
1347
- });
1348
- const onFirstClick = () => {
1349
- setPath(PATH_1);
1350
- deps = [2];
1351
- onExtChange = onSecondExtChange;
1352
- };
1353
- const onSecondClick = () => {
1354
- setPath('');
1355
- };
1356
- return (_jsxs(Provider, { children: [_jsx(A, {}), _jsx("button", { onClick: onFirstClick, children: firstButtonText }), _jsx("button", { onClick: onSecondClick, children: secondButtonText })] }));
1357
- };
1358
- render(_jsx(B, {}));
1359
- expect(onFirstExtChange).toHaveBeenCalledTimes(0);
1360
- fireEvent.click(screen.getByText(firstButtonText));
1361
- expect(onFirstExtChange).toHaveBeenCalledTimes(1);
1362
- expect(onSecondExtChange).toHaveBeenCalledTimes(0);
1363
- fireEvent.click(screen.getByText(secondButtonText));
1364
- expect(onFirstExtChange).toHaveBeenCalledTimes(1);
1365
- expect(onSecondExtChange).toHaveBeenCalledTimes(1);
1366
- expect(onSecondExtChange).toHaveBeenLastCalledWith({
1367
- fieldPaths: ['ext'],
1368
- newEntity: defaultFile,
1369
- oldEntity: { ...defaultFile, ext: EXT_1, path: PATH_1 },
1370
- newValue: '',
1371
- oldValue: EXT_1,
1372
- });
1373
- });
1374
- test.each([UseCaseModes.Normal, UseCaseModes.Stateless])('`options.watch` should not be updated in child element if `deps` has not changed', (mode) => {
1375
- const onFirstExtChange = jest.fn();
1376
- const onSecondExtChange = jest.fn();
1377
- let onExtChange = onFirstExtChange;
1378
- const firstButtonText = 'first button';
1379
- const secondButtonText = 'second button';
1380
- const A = () => {
1381
- useUseCase(fileUseCase, {
1382
- watch: {
1383
- ext: onExtChange,
1384
- },
1385
- }, []);
1386
- return _jsx(Fragment, {});
1387
- };
1388
- const B = () => {
1389
- const [, { setPath }, Provider] = useUseCase(defaultFile, fileUseCase, mode);
1390
- const onFirstClick = () => {
1391
- setPath(PATH_1);
1392
- onExtChange = onSecondExtChange;
1393
- };
1394
- const onSecondClick = () => {
1395
- setPath('');
1396
- };
1397
- return (_jsxs(Provider, { children: [_jsx(A, {}), _jsx("button", { onClick: onFirstClick, children: firstButtonText }), _jsx("button", { onClick: onSecondClick, children: secondButtonText })] }));
1398
- };
1399
- render(_jsx(B, {}));
1400
- expect(onFirstExtChange).toHaveBeenCalledTimes(0);
1401
- fireEvent.click(screen.getByText(firstButtonText));
1402
- expect(onFirstExtChange).toHaveBeenCalledTimes(1);
1403
- expect(onSecondExtChange).toHaveBeenCalledTimes(0);
1404
- fireEvent.click(screen.getByText(secondButtonText));
1405
- expect(onFirstExtChange).toHaveBeenCalledTimes(2);
1406
- expect(onSecondExtChange).toHaveBeenCalledTimes(0);
1407
- expect(onFirstExtChange).toHaveBeenLastCalledWith({
1408
- fieldPaths: ['ext'],
1409
- newEntity: defaultFile,
1410
- oldEntity: { ...defaultFile, ext: EXT_1, path: PATH_1 },
1411
- newValue: '',
1412
- oldValue: EXT_1,
1413
- });
1414
- });
1415
1279
  test('`options.onChange` event should be trigger in orders', () => {
1416
1280
  let changeTimes = 0;
1417
1281
  const updateChangeTimes = () => {
@@ -1445,23 +1309,65 @@ describe('useUseCase', () => {
1445
1309
  expect(onChangeB).toHaveReturnedWith(1);
1446
1310
  expect(onChangeC).toHaveReturnedWith(3);
1447
1311
  });
1312
+ test.each([UseCaseModes.Normal, UseCaseModes.Stateless])('[mode=%s]: `options.onChange` should always trigger the latest one in child components', (mode) => {
1313
+ const onFirstChange = jest.fn();
1314
+ const onSecondChange = jest.fn();
1315
+ let onChange = onFirstChange;
1316
+ const firstButtonText = 'first button';
1317
+ const secondButtonText = 'second button';
1318
+ const A = () => {
1319
+ const [, { setPath }] = useUseCase(fileUseCase, {
1320
+ onChange,
1321
+ });
1322
+ const onFirstClick = () => {
1323
+ setPath(PATH_1);
1324
+ onChange = onSecondChange;
1325
+ };
1326
+ const onSecondClick = () => {
1327
+ setPath('');
1328
+ };
1329
+ return (_jsxs(Fragment, { children: [_jsx("button", { onClick: onFirstClick, children: firstButtonText }), _jsx("button", { onClick: onSecondClick, children: secondButtonText })] }));
1330
+ };
1331
+ const B = () => {
1332
+ const [file, setFile] = useState(defaultFile);
1333
+ const [, , Provider] = useUseCase(file, fileUseCase, mode, {
1334
+ onChange(newFile) {
1335
+ if ((mode & UseCaseModes.Stateless) !== UseCaseModes.Stateless) {
1336
+ return;
1337
+ }
1338
+ // `stateless` 不会保存状态,所以需要手动保存
1339
+ setFile(newFile);
1340
+ },
1341
+ });
1342
+ return (_jsx(Provider, { children: _jsx(A, {}) }));
1343
+ };
1344
+ render(_jsx(B, {}));
1345
+ expect(onFirstChange).toHaveBeenCalledTimes(0);
1346
+ fireEvent.click(screen.getByText(firstButtonText));
1347
+ expect(onFirstChange).toHaveBeenCalledTimes(1);
1348
+ expect(onSecondChange).toHaveBeenCalledTimes(0);
1349
+ fireEvent.click(screen.getByText(secondButtonText));
1350
+ expect(onFirstChange).toHaveBeenCalledTimes(1);
1351
+ expect(onSecondChange).toHaveBeenCalledTimes(1);
1352
+ expect(onSecondChange).toHaveBeenLastCalledWith(defaultFile, { ...defaultFile, ext: EXT_1, path: PATH_1 });
1353
+ });
1448
1354
  test('`options.watch` should be trigger at child elements', () => {
1449
1355
  const onExtChange = jest.fn();
1450
1356
  const firstButtonText = 'first button';
1451
1357
  const A = () => {
1452
- useUseCase(fileUseCase, {
1358
+ const [, { setPath }] = useUseCase(fileUseCase, {
1453
1359
  watch: {
1454
1360
  ext: onExtChange,
1455
1361
  },
1456
1362
  });
1457
- return _jsx(Fragment, {});
1458
- };
1459
- const B = () => {
1460
- const [, { setPath }, Provider] = useUseCase(defaultFile, fileUseCase, {});
1461
1363
  const onFirstClick = () => {
1462
1364
  setPath(PATH_1);
1463
1365
  };
1464
- return (_jsxs(Provider, { children: [_jsx(A, {}), _jsx("button", { onClick: onFirstClick, children: firstButtonText })] }));
1366
+ return _jsx("button", { onClick: onFirstClick, children: firstButtonText });
1367
+ };
1368
+ const B = () => {
1369
+ const [, , Provider] = useUseCase(defaultFile, fileUseCase, {});
1370
+ return (_jsx(Provider, { children: _jsx(A, {}) }));
1465
1371
  };
1466
1372
  render(_jsx(B, {}));
1467
1373
  expect(onExtChange).toHaveBeenCalledTimes(0);
@@ -1519,6 +1425,56 @@ describe('useUseCase', () => {
1519
1425
  expect(onChangeB).toHaveReturnedWith(1);
1520
1426
  expect(onChangeC).toHaveReturnedWith(3);
1521
1427
  });
1428
+ test.each([UseCaseModes.Normal, UseCaseModes.Stateless])('[mode=%s]: `options.watch` should trigger the latest one in child components', (mode) => {
1429
+ const onFirstExtChange = jest.fn();
1430
+ const onSecondExtChange = jest.fn();
1431
+ let onExtChange = onFirstExtChange;
1432
+ const firstButtonText = 'first button';
1433
+ const secondButtonText = 'second button';
1434
+ const A = () => {
1435
+ const [, { setPath }] = useUseCase(fileUseCase, {
1436
+ watch: {
1437
+ ext: onExtChange,
1438
+ },
1439
+ });
1440
+ const onFirstClick = () => {
1441
+ setPath(PATH_1);
1442
+ onExtChange = onSecondExtChange;
1443
+ };
1444
+ const onSecondClick = () => {
1445
+ setPath('');
1446
+ };
1447
+ return (_jsxs(Fragment, { children: [_jsx("button", { onClick: onFirstClick, children: firstButtonText }), _jsx("button", { onClick: onSecondClick, children: secondButtonText })] }));
1448
+ };
1449
+ const B = () => {
1450
+ const [file, setFile] = useState(defaultFile);
1451
+ const [, , Provider] = useUseCase(file, fileUseCase, mode, {
1452
+ onChange(newFile) {
1453
+ if ((mode & UseCaseModes.Stateless) !== UseCaseModes.Stateless) {
1454
+ return;
1455
+ }
1456
+ // `stateless` 不会保存状态,所以需要手动保存
1457
+ setFile(newFile);
1458
+ },
1459
+ });
1460
+ return (_jsx(Provider, { children: _jsx(A, {}) }));
1461
+ };
1462
+ render(_jsx(B, {}));
1463
+ expect(onFirstExtChange).toHaveBeenCalledTimes(0);
1464
+ fireEvent.click(screen.getByText(firstButtonText));
1465
+ expect(onFirstExtChange).toHaveBeenCalledTimes(1);
1466
+ expect(onSecondExtChange).toHaveBeenCalledTimes(0);
1467
+ fireEvent.click(screen.getByText(secondButtonText));
1468
+ expect(onFirstExtChange).toHaveBeenCalledTimes(1);
1469
+ expect(onSecondExtChange).toHaveBeenCalledTimes(1);
1470
+ expect(onSecondExtChange).toHaveBeenLastCalledWith({
1471
+ fieldPaths: ['ext'],
1472
+ newEntity: defaultFile,
1473
+ oldEntity: { ...defaultFile, ext: EXT_1, path: PATH_1 },
1474
+ newValue: '',
1475
+ oldValue: EXT_1,
1476
+ });
1477
+ });
1522
1478
  });
1523
1479
  describe('`useUseCase` should work the same as `useReducers`', () => {
1524
1480
  test('`entity` should equal `defaultFile`', () => {
@@ -0,0 +1,2 @@
1
+ import { CaptureCallFactory } from './types';
2
+ export declare const captureCalls: <T extends object>(obj: T, callback: CaptureCallFactory) => T;
@@ -0,0 +1,14 @@
1
+ export const captureCalls = (obj, callback) => {
2
+ const newObj = {};
3
+ Object.keys(obj).forEach((key) => {
4
+ const value = obj[key];
5
+ if (typeof value === 'function') {
6
+ newObj[key] = ((...args) => {
7
+ return callback(key, args);
8
+ });
9
+ return;
10
+ }
11
+ newObj[key] = value;
12
+ });
13
+ return newObj;
14
+ };
@@ -0,0 +1,4 @@
1
+ import { RestArguments } from '@mic-rexjs/usecases/es/types';
2
+ export interface CaptureCallFactory {
3
+ <T>(key: string, args: RestArguments): T;
4
+ }
@@ -22,6 +22,7 @@ var useEntity = exports.useEntity = function useEntity(statuses, rootEntity, con
22
22
  var renderingEntity = (0, _getRenderingEntity.getRenderingEntity)(statuses, entityState, rootEntity, contextEntity);
23
23
  var entityEnabled = (statuses & _UseCaseStatuses.UseCaseStatuses.EntityEnabled) === _UseCaseStatuses.UseCaseStatuses.EntityEnabled;
24
24
  var entityRootEnabled = (statuses & _UseCaseStatuses.UseCaseStatuses.EntityRootEnabled) === _UseCaseStatuses.UseCaseStatuses.EntityRootEnabled;
25
+ var optionsRef = (0, _ahooks.useLatest)(options);
25
26
  var store = (0, _useContextualItem.useContextualItem)(contextStore, statuses, function () {
26
27
  if (!entityRootEnabled) {
27
28
  return new _usecases.EntityStore(null);
@@ -36,10 +37,18 @@ var useEntity = exports.useEntity = function useEntity(statuses, rootEntity, con
36
37
  }
37
38
  });
38
39
  });
39
- var rewatch = (0, _ahooks.useMemoizedFn)(function () {
40
- var onChange = options.onChange,
41
- watch = options.watch;
40
+ if (entityRootEnabled) {
41
+ // 执行同步操作
42
+ store.value = renderingEntity;
43
+ }
44
+ (0, _react.useEffect)(function () {
45
+ if (!entityEnabled) {
46
+ return;
47
+ }
42
48
  var onEntityChange = function onEntityChange(newEntity, oldEntity) {
49
+ var _optionsRef$current = optionsRef.current,
50
+ onChange = _optionsRef$current.onChange,
51
+ watch = _optionsRef$current.watch;
43
52
  if (watch) {
44
53
  (0, _triggerWatchers.triggerWatchers)(watch, newEntity, oldEntity);
45
54
  }
@@ -49,17 +58,7 @@ var useEntity = exports.useEntity = function useEntity(statuses, rootEntity, con
49
58
  return function () {
50
59
  store.unwatch(onEntityChange);
51
60
  };
52
- });
53
- if (entityRootEnabled) {
54
- // 执行同步操作
55
- store.value = renderingEntity;
56
- }
57
- (0, _react.useEffect)(function () {
58
- if (!entityEnabled) {
59
- return;
60
- }
61
- return rewatch();
62
- }, [entityEnabled, store, depsKey, rewatch]);
61
+ }, [entityEnabled, store, depsKey, optionsRef]);
63
62
  return (0, _ahooks.useCreation)(function () {
64
63
  return [renderingEntity, store];
65
64
  }, [renderingEntity, store]);