@mic-rexjs/usecases-react 1.7.8 → 2.0.0
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/README.md +1 -1
- package/dist/index.min.js +1 -1
- package/es/configs/defaultUseCaseContext/index.d.ts +2 -3
- package/es/configs/defaultUseCaseContext/index.js +1 -1
- package/es/configs/defaultUseCaseContext/types.d.ts +11 -3
- package/es/configs/usecaseContextMap/types.d.ts +2 -5
- package/es/enums/UseCaseModes/index.d.ts +6 -0
- package/es/enums/UseCaseModes/index.js +7 -0
- package/es/hooks/useChangeCallbackCollection/index.d.ts +3 -0
- package/es/hooks/useChangeCallbackCollection/index.js +29 -0
- package/es/hooks/useGlobalUseCase/index.d.ts +2 -0
- package/es/hooks/useGlobalUseCase/index.js +11 -0
- package/es/hooks/useGlobalUseCase/index.test.js +71 -0
- package/es/hooks/useGlobalUseCase/types.d.ts +12 -0
- package/es/hooks/useGlobalUseCase/types.js +1 -0
- package/es/hooks/useProvider/index.d.ts +3 -5
- package/es/hooks/useProvider/index.js +25 -15
- package/es/hooks/useProvider/types.d.ts +5 -1
- package/es/hooks/useStatelessUseCase/index.d.ts +2 -0
- package/es/hooks/useStatelessUseCase/index.js +8 -0
- package/es/hooks/useStatelessUseCase/index.test.d.ts +1 -0
- package/es/hooks/useStatelessUseCase/index.test.js +75 -0
- package/es/hooks/useStatelessUseCase/types.d.ts +5 -0
- package/es/hooks/useStatelessUseCase/types.js +1 -0
- package/es/hooks/useUseCase/index.js +27 -29
- package/es/hooks/useUseCase/index.test.js +273 -202
- package/es/hooks/useUseCase/types.d.ts +55 -8
- package/es/hooks/useUseCaseContext/index.d.ts +2 -2
- package/es/hooks/useUseCaseContext/index.js +1 -1
- package/es/index.d.ts +2 -0
- package/es/index.js +2 -0
- package/es/methods/getRootEntity/index.d.ts +2 -1
- package/es/methods/getRootEntity/index.js +6 -5
- package/es/methods/initEntityReducers/index.js +1 -1
- package/es/methods/toMaxArguments/index.d.ts +3 -0
- package/es/methods/toMaxArguments/index.js +28 -0
- package/es/methods/triggerCallbacks/index.d.ts +2 -3
- package/es/methods/triggerCallbacks/index.js +3 -12
- package/lib/configs/defaultUseCaseContext/index.js +1 -1
- package/lib/enums/UseCaseModes/index.js +14 -0
- package/lib/hooks/useChangeCallbackCollection/index.js +37 -0
- package/lib/hooks/useGlobalUseCase/index.js +25 -0
- package/lib/hooks/useGlobalUseCase/index.test.js +78 -0
- package/lib/hooks/useProvider/index.js +30 -20
- package/lib/hooks/useStatelessUseCase/index.js +22 -0
- package/lib/hooks/useStatelessUseCase/index.test.js +78 -0
- package/lib/hooks/useStatelessUseCase/types.js +5 -0
- package/lib/hooks/useUseCase/index.js +40 -31
- package/lib/hooks/useUseCase/index.test.js +380 -281
- package/lib/hooks/useUseCaseContext/index.js +1 -1
- package/lib/index.js +15 -1
- package/lib/methods/getRootEntity/index.js +6 -5
- package/lib/methods/initEntityReducers/index.js +2 -3
- package/lib/methods/toMaxArguments/index.js +25 -0
- package/lib/methods/triggerCallbacks/index.js +3 -13
- package/package.json +1 -1
- package/es/hooks/useOptionsRefCollection/index.d.ts +0 -3
- package/es/hooks/useOptionsRefCollection/index.js +0 -22
- package/es/hooks/useOptionsRefCollection/types.d.ts +0 -2
- package/lib/hooks/useOptionsRefCollection/index.js +0 -29
- /package/es/hooks/{useOptionsRefCollection/types.js → useGlobalUseCase/index.test.d.ts} +0 -0
- /package/lib/hooks/{useOptionsRefCollection → useGlobalUseCase}/types.js +0 -0
package/README.md
CHANGED
|
@@ -114,8 +114,8 @@ const fileUseCase = <T extends File>({ maxContentLength = 2000 }: FileUseCaseOpt
|
|
|
114
114
|
};
|
|
115
115
|
|
|
116
116
|
// b.tsx
|
|
117
|
-
import { useUseCase } from '@mic-rexjs/usecases-react';
|
|
118
117
|
import ReactDOM from 'react-dom';
|
|
118
|
+
import { useUseCase } from '@mic-rexjs/usecases-react';
|
|
119
119
|
|
|
120
120
|
const ParentComponent = ({ children }: React.PropsWithChildren): React.ReactElement => {
|
|
121
121
|
// Pass a default entity to initialize usecase, this usecase must be unique, just like `react context`.
|
package/dist/index.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! For license information please see index.min.js.LICENSE.txt */
|
|
2
|
-
!function(e,r){if("object"==typeof exports&&"object"==typeof module)module.exports=r(require("react"),require("ahooks"),require("@mic-rexjs/usecases"));else if("function"==typeof define&&define.amd)define(["react","ahooks","@mic-rexjs/usecases"],r);else{var t="object"==typeof exports?r(require("react"),require("ahooks"),require("@mic-rexjs/usecases")):r(e.react,e.ahooks,e["@mic-rexjs/usecases"]);for(var n in t)("object"==typeof exports?exports:e)[n]=t[n]}}(this,((e,r,t)=>(()=>{"use strict";var n={251:(e,r,t)=>{var n=t(156),o=Symbol.for("react.element"),u=(Symbol.for("react.fragment"),Object.prototype.hasOwnProperty),
|
|
2
|
+
!function(e,r){if("object"==typeof exports&&"object"==typeof module)module.exports=r(require("react"),require("ahooks"),require("@mic-rexjs/usecases"));else if("function"==typeof define&&define.amd)define(["react","ahooks","@mic-rexjs/usecases"],r);else{var t="object"==typeof exports?r(require("react"),require("ahooks"),require("@mic-rexjs/usecases")):r(e.react,e.ahooks,e["@mic-rexjs/usecases"]);for(var n in t)("object"==typeof exports?exports:e)[n]=t[n]}}(this,((e,r,t)=>(()=>{"use strict";var n={251:(e,r,t)=>{var n=t(156),o=Symbol.for("react.element"),u=(Symbol.for("react.fragment"),Object.prototype.hasOwnProperty),a=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,i={key:!0,ref:!0,__self:!0,__source:!0};r.jsx=function(e,r,t){var n,c={},l=null,f=null;for(n in void 0!==t&&(l=""+t),void 0!==r.key&&(l=""+r.key),void 0!==r.ref&&(f=r.ref),r)u.call(r,n)&&!i.hasOwnProperty(n)&&(c[n]=r[n]);if(e&&e.defaultProps)for(n in r=e.defaultProps)void 0===c[n]&&(c[n]=r[n]);return{$$typeof:o,type:e,key:l,ref:f,props:c,_owner:a.current}}},893:(e,r,t)=>{e.exports=t(251)},112:e=>{e.exports=t},749:e=>{e.exports=r},156:r=>{r.exports=e}},o={};function u(e){var r=o[e];if(void 0!==r)return r.exports;var t=o[e]={exports:{}};return n[e](t,t.exports,u),t.exports}u.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return u.d(r,{a:r}),r},u.d=(e,r)=>{for(var t in r)u.o(r,t)&&!u.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},u.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),u.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var a={};return(()=>{u.r(a),u.d(a,{UseCaseFragment:()=>E,useGlobalUseCase:()=>k,useStatelessUseCase:()=>M,useUseCase:()=>A});var e=u(893),r=u(156),t=u.n(r);function n(e,r){(null==r||r>e.length)&&(r=e.length);for(var t=0,n=new Array(r);t<r;t++)n[t]=e[t];return n}function o(e,r){if(e){if("string"==typeof e)return n(e,r);var t=Object.prototype.toString.call(e).slice(8,-1);return"Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t?Array.from(e):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?n(e,r):void 0}}function i(e,r){return function(e){if(Array.isArray(e))return e}(e)||function(e,r){var t=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=t){var n,o,u,a,i=[],c=!0,l=!1;try{if(u=(t=t.call(e)).next,0===r){if(Object(t)!==t)return;c=!1}else for(;!(c=(n=u.call(t)).done)&&(i.push(n.value),i.length!==r);c=!0);}catch(e){l=!0,o=e}finally{try{if(!c&&null!=t.return&&(a=t.return(),Object(a)!==a))return}finally{if(l)throw o}}return i}}(e,r)||o(e,r)||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.")}()}var c,l=u(749),f=function(e){return i((0,r.useState)(e),1)[0]},s=function(e){return i((0,r.useState)((function(){return e})),1)[0]};!function(e){e[e.Normal=2]="Normal",e[e.Stateless=4]="Stateless",e[e.Global=8]="Global",e[e.StatelessGlobal=12]="StatelessGlobal"}(c||(c={}));var y=function(e,r){var t=e.length;if(t!==r.length)return!1;for(var n=0;n<t;n++)if(e[n]!==r[n])return!1;return!0},p=function(e){var t=(0,r.useRef)(0),n=(0,r.useRef)([]),o=n.current,u=y(e,o);return n.current=e,t.current+=u?0:1,t.current};function v(e){return v="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},v(e)}function b(e,r,t){return(r=function(e){var r=function(e,r){if("object"!==v(e)||null===e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var n=t.call(e,"string");if("object"!==v(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"===v(r)?r:String(r)}(r))in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}var d=u(112),m=["watch","onChange","options"];function h(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function g(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?h(Object(t),!0).forEach((function(r){b(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):h(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}var O=new Map,j=(0,r.createContext)(null),S=function(e,r){for(var t={},n={},o=function(){var e=i(a[u],2),o=e[0],c=e[1];n[o]=function(){for(var e=t[o],n=r(),u=arguments.length,a=new Array(u),i=0;i<u;i++)a[i]=arguments[i];if(e&&n){var l=e.parameters,f=e.returnValue;if(y(l,a))return f}var s=c.apply(void 0,a);return n&&(t[o]={parameters:a,returnValue:s}),s}},u=0,a=Object.entries(e);u<a.length;u++)o();return n},w=function(e,r){var t=e.indexOf(r);-1!==t&&e.splice(t,1)};function C(e){return function(e){if(Array.isArray(e))return n(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||o(e)||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 x=function(e,r){return"object"===v(e)&&null!==e&&Object.hasOwn(e,r)},P=function e(r,t,n,o){var u=arguments.length>4&&void 0!==arguments[4]?arguments[4]:[],a=void 0,c=i(n.match(/^([^.]+)\.(.+)$/)||[],3),l=c[1],f=void 0===l?n:l,s=c[2],y=void 0===s?"":s,p=x(r,f),v=x(t,f),b=[].concat(C(u),[f]);if(p||v){var d=p?r[f]:a,m=v?t[f]:a;if(y)return void e(d,m,y,o,b);if(d===m)return;o(d,m,b)}else if(!/^\d+^/.test(f))for(var h=Array.isArray(r)?r:[],g=Array.isArray(t)?t:[],O=h.length,j=g.length,S=Math.max(O,j),w=0;w<S;w++)e(h[w],g[w],n,o,[].concat(C(u),["".concat(w)]))},_=function(e,r,t){for(var n=function(){var e=i(u[o],2),n=e[0],a=e[1];P(t,r,n,(function(e,n,o){a({fieldPaths:o,newEntity:r,oldEntity:t,newValue:n,oldValue:e})}))},o=0,u=Object.entries(e);o<u.length;o++)n()},A=function(){for(var e=arguments.length,n=new Array(e),o=0;o<e;o++)n[o]=arguments[o];var u,a=function(e){var r=i(e,5),t=r[0],n=r[1],o=r[2],u=r[3],a=r[4];return"function"!=typeof n?[null,t,c.Normal,n||{},o||[]]:"number"==typeof o?[t,n,o,u||{},a||[]]:[t,n,c.Normal,o||{},u||[]]}(n),y=i(a,5),v=y[0],b=y[1],h=y[2],C=y[3],x=y[4],P=i((0,r.useState)(v),2),A=P[0],E=P[1],k=s(b),M=k,R=f(h),G=p(x),I=((u=(0,r.useRef)(!0)).current=!0,(0,r.useEffect)((function(){u.current=!1})),u),U=f("function"==typeof n[1]),F=function(e,t){return f((function(){var n=O;if(n.has(e))return n.get(e);if(t)return t;var o=(0,r.createContext)(null);return n.set(e,o),o}))}(M,U?null:j),T=(0,r.useContext)(F),N=null!==T,q=(null==T?void 0:T())||{},D=q.entity,z=q.reducers,L=void 0===z?null:z,V=q.changeCallbackCollection,$=U||N,B=function(e,r,t){var n=(0,l.useCreation)((function(){return e?[]:r}),[r,e]),o=(0,l.useMemoizedFn)((function(e,r){var n=t.onChange,o=t.watch;o&&_(o,e,r),null==n||n(e,r)})),u=(0,l.usePrevious)(n);return(0,l.useCreation)((function(){u&&w(u,o),n.push(o)}),[o,n,u]),(0,l.useUnmount)((function(){w(n,o)})),n}(U||!N,void 0===V?null:V,C),W=(0,l.useCreation)((function(){return U?function(e,r,t){return(t&c.Stateless)!==c.Stateless?e:"function"==typeof r?r():r}(A,v,R):D}),[U,D,R,A,v]),Y=(0,l.useMemoizedFn)((function(e,r){(R&c.Stateless)!==c.Stateless&&E(e),function(e,r,t){for(var n=e.length;n>0;n--)e[n-1](r,t)}(B,e,r)})),H=(0,l.useMemoizedFn)((function(){return function(e,r,t,n){var o=(0,d.entityReducerUseCase)().createEntityReducers,u=(t.watch,t.onChange,t.options);return o(e,r,g(g(g({},function(e,r){if(null==e)return{};var t,n,o=function(e,r){if(null==e)return{};var t,n,o={},u=Object.keys(e);for(n=0;n<u.length;n++)t=u[n],r.indexOf(t)>=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var u=Object.getOwnPropertySymbols(e);for(n=0;n<u.length;n++)t=u[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(t,m)),u),{},{onChange:n,onGenerate:function(e,r){return r}}))}(W,M,C,Y)})),J=(0,l.useMemoizedFn)((function(){return k(C)})),K=(0,l.useCreation)((function(){return U?H():null}),[U,G,H]),Q=(0,l.useCreation)((function(){return K||L||{}}),[K,L]),X=(0,l.useCreation)((function(){return $?{}:J()}),[$,G,J]),Z=function(e,n,o,u,a){var i=(n&c.Global)===c.Global,f=(0,l.useLatest)({entity:o,reducers:u,changeCallbackCollection:a}),y=p(i?[]:[o,u,a]),v=(0,r.useCallback)((function(){return f.current}),[y,f]),b=(0,l.useLatest)(v);return s((function(r){var n=r.children,o=r.with,u=void 0===o?[]:o,a=e.Provider;return t().createElement(a,{value:b.current},u.reduceRight((function(e,r){return t().createElement(r,{},e)}),n))}))}(F,R,W,Q,B),ee=(0,l.useMemoizedFn)((function(e,r){return[e,S(r,(function(){return I.current})),U?Z:null]}));return(0,l.useCreation)((function(){return $?ee(W,Q):X}),[$,W,Q,X,ee])},E=function(t){var n=t.usecase,o=t.watch,u=t.onChange;return A(n,{watch:o,onChange:u}),(0,e.jsx)(r.Fragment,{})},k=function(){for(var e=arguments.length,r=new Array(e),t=0;t<e;t++)r[t]=arguments[t];var n=r[0],o=r[1],u=r.slice(2),a="function"==typeof o,i=A.apply(void 0,C(a?[n,o,c.Global].concat(C(u)):r));return a?i:i[1]},M=function(){for(var e=arguments.length,r=new Array(e),t=0;t<e;t++)r[t]=arguments[t];var n=r[0],o=r[1],u=r.slice(2),a="function"==typeof o;return A.apply(void 0,C(a?[n,o,c.Stateless].concat(C(u)):r))}})(),a})()));
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
1
|
import { EntityReducers } from '@mic-rexjs/usecases';
|
|
3
|
-
import {
|
|
4
|
-
export declare const defaultUseCaseContext:
|
|
2
|
+
import { UseCaseContext } from './types';
|
|
3
|
+
export declare const defaultUseCaseContext: UseCaseContext<unknown, EntityReducers<unknown>>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { createContext } from 'react';
|
|
2
|
-
export const defaultUseCaseContext = createContext(
|
|
2
|
+
export const defaultUseCaseContext = createContext(null);
|
|
@@ -1,11 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference types="react" />
|
|
2
2
|
import { AsyncEntityGenerator, EntityGenerator, EntityReducer, EntityReducers } from '@mic-rexjs/usecases';
|
|
3
3
|
export type ContextualEntityReducer<T, TReducer extends EntityReducer<T>> = TReducer extends (entity: T, ...args: infer TArgs) => infer TReturn ? (...args: TArgs) => TReturn extends AsyncEntityGenerator<T, infer TResult> ? Promise<TResult> : TReturn extends EntityGenerator<T, infer TResult> ? TResult : TReturn : never;
|
|
4
4
|
export type ContextualEntityReducers<T, TEntityReducers extends EntityReducers<T>> = {
|
|
5
5
|
[K in keyof TEntityReducers]: ContextualEntityReducer<T, TEntityReducers[K]>;
|
|
6
6
|
};
|
|
7
|
-
export interface
|
|
7
|
+
export interface ChangeCallback<T> {
|
|
8
|
+
(newEntity: T, oldEntity: T): void;
|
|
9
|
+
}
|
|
10
|
+
export interface UseCaseContextValue<T, TEntityReducers extends EntityReducers<T>> {
|
|
8
11
|
entity?: T;
|
|
9
12
|
reducers?: ContextualEntityReducers<T, TEntityReducers>;
|
|
10
|
-
|
|
13
|
+
changeCallbackCollection?: ChangeCallback<T>[];
|
|
14
|
+
}
|
|
15
|
+
export interface UseCaseContextValueGetter<T, TEntityReducers extends EntityReducers<T>> {
|
|
16
|
+
(): UseCaseContextValue<T, TEntityReducers>;
|
|
17
|
+
}
|
|
18
|
+
export interface UseCaseContext<T, TEntityReducers extends EntityReducers<T>> extends React.Context<UseCaseContextValueGetter<T, TEntityReducers> | null> {
|
|
11
19
|
}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
1
|
import { EntityReducers, EntityUseCase } from '@mic-rexjs/usecases';
|
|
3
|
-
import {
|
|
4
|
-
export interface
|
|
5
|
-
}
|
|
6
|
-
export interface UseCaseContextMap<T, TEntityReducers extends EntityReducers<T>, TUseCaseOptions extends object = object> extends Map<EntityUseCase<T, TEntityReducers, TUseCaseOptions>, UseCaseMappingContext<T, TEntityReducers, TUseCaseOptions>> {
|
|
2
|
+
import { UseCaseContext } from '../defaultUseCaseContext/types';
|
|
3
|
+
export interface UseCaseContextMap<T, TEntityReducers extends EntityReducers<T>, TUseCaseOptions extends object = object> extends Map<EntityUseCase<T, TEntityReducers, TUseCaseOptions>, UseCaseContext<T, TEntityReducers>> {
|
|
7
4
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export var UseCaseModes;
|
|
2
|
+
(function (UseCaseModes) {
|
|
3
|
+
UseCaseModes[UseCaseModes["Normal"] = 2] = "Normal";
|
|
4
|
+
UseCaseModes[UseCaseModes["Stateless"] = 4] = "Stateless";
|
|
5
|
+
UseCaseModes[UseCaseModes["Global"] = 8] = "Global";
|
|
6
|
+
UseCaseModes[UseCaseModes["StatelessGlobal"] = 12] = "StatelessGlobal";
|
|
7
|
+
})(UseCaseModes || (UseCaseModes = {}));
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { UseCaseHookOptions } from '../useUseCase/types';
|
|
2
|
+
import { ChangeCallback } from '../../configs/defaultUseCaseContext/types';
|
|
3
|
+
export declare const useChangeCallbackCollection: <T, TUseCaseOptions extends object, TOptions extends UseCaseHookOptions<T, TUseCaseOptions> = UseCaseHookOptions<T, TUseCaseOptions>>(isRoot: boolean, contextCollection: ChangeCallback<T>[] | null, options: TOptions) => ChangeCallback<T>[];
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useCreation, useMemoizedFn, usePrevious, useUnmount } from 'ahooks';
|
|
2
|
+
import { removeItem } from '../../methods/removeItem';
|
|
3
|
+
import { triggerWatchers } from '../../methods/triggerWatchers';
|
|
4
|
+
export const useChangeCallbackCollection = (isRoot, contextCollection, options) => {
|
|
5
|
+
const changeCallbackCollection = useCreation(() => {
|
|
6
|
+
if (isRoot) {
|
|
7
|
+
return [];
|
|
8
|
+
}
|
|
9
|
+
return contextCollection;
|
|
10
|
+
}, [contextCollection, isRoot]);
|
|
11
|
+
const onEntityChange = useMemoizedFn((newEntity, oldEntity) => {
|
|
12
|
+
const { onChange, watch } = options;
|
|
13
|
+
if (watch) {
|
|
14
|
+
triggerWatchers(watch, newEntity, oldEntity);
|
|
15
|
+
}
|
|
16
|
+
onChange?.(newEntity, oldEntity);
|
|
17
|
+
});
|
|
18
|
+
const prevChangeCallbackCollection = usePrevious(changeCallbackCollection);
|
|
19
|
+
useCreation(() => {
|
|
20
|
+
if (prevChangeCallbackCollection) {
|
|
21
|
+
removeItem(prevChangeCallbackCollection, onEntityChange);
|
|
22
|
+
}
|
|
23
|
+
changeCallbackCollection.push(onEntityChange);
|
|
24
|
+
}, [onEntityChange, changeCallbackCollection, prevChangeCallbackCollection]);
|
|
25
|
+
useUnmount(() => {
|
|
26
|
+
removeItem(changeCallbackCollection, onEntityChange);
|
|
27
|
+
});
|
|
28
|
+
return changeCallbackCollection;
|
|
29
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { useUseCase } from '../useUseCase';
|
|
2
|
+
import { UseCaseModes } from '../../enums/UseCaseModes';
|
|
3
|
+
export const useGlobalUseCase = ((...args) => {
|
|
4
|
+
const [arg1, arg2, ...rest] = args;
|
|
5
|
+
const isContextRoot = typeof arg2 === 'function';
|
|
6
|
+
const coreCollection = useUseCase(...(isContextRoot ? [arg1, arg2, UseCaseModes.Global, ...rest] : args));
|
|
7
|
+
if (isContextRoot) {
|
|
8
|
+
return coreCollection;
|
|
9
|
+
}
|
|
10
|
+
return coreCollection[1];
|
|
11
|
+
});
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useGlobalUseCase } from '.';
|
|
3
|
+
import { entityUseCase } from '@mic-rexjs/usecases';
|
|
4
|
+
import { describe, expect, jest, test } from '@jest/globals';
|
|
5
|
+
import { UseCaseModes } from '../../enums/UseCaseModes';
|
|
6
|
+
import { render, renderHook } from '@testing-library/react';
|
|
7
|
+
import { useMount } from 'ahooks';
|
|
8
|
+
import * as useUseCaseModule from '../useUseCase';
|
|
9
|
+
const numberUseCase = () => {
|
|
10
|
+
return entityUseCase();
|
|
11
|
+
};
|
|
12
|
+
describe('useGlobalUseCase', () => {
|
|
13
|
+
describe('`useGlobalUseCase` should work the same as `RootCoreCollectionHook`', () => {
|
|
14
|
+
test('check `useUseCase` has received correct arguments', () => {
|
|
15
|
+
const useMockedUseCase = jest.fn();
|
|
16
|
+
jest.spyOn(useUseCaseModule, 'useUseCase').mockImplementation(useMockedUseCase);
|
|
17
|
+
renderHook(() => {
|
|
18
|
+
useGlobalUseCase(1, numberUseCase);
|
|
19
|
+
});
|
|
20
|
+
expect(useMockedUseCase).toHaveBeenCalledWith(1, numberUseCase, UseCaseModes.Global);
|
|
21
|
+
jest.spyOn(useUseCaseModule, 'useUseCase').mockRestore();
|
|
22
|
+
});
|
|
23
|
+
test('should should return `CoreCollection` with Provider', () => {
|
|
24
|
+
const { result } = renderHook(() => {
|
|
25
|
+
return useGlobalUseCase(1, numberUseCase);
|
|
26
|
+
});
|
|
27
|
+
const { current } = result;
|
|
28
|
+
expect(current).toEqual([
|
|
29
|
+
1,
|
|
30
|
+
{
|
|
31
|
+
setEntity: expect.any(Function),
|
|
32
|
+
},
|
|
33
|
+
expect.any(Function),
|
|
34
|
+
]);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
describe('`useGlobalUseCase` should work the same as `GlobalReducersHook`', () => {
|
|
38
|
+
test('check `useUseCase` has received correct arguments', () => {
|
|
39
|
+
const useMockedUseCase = jest.fn();
|
|
40
|
+
jest.spyOn(useUseCaseModule, 'useUseCase').mockImplementation(useMockedUseCase);
|
|
41
|
+
renderHook(() => {
|
|
42
|
+
try {
|
|
43
|
+
useGlobalUseCase(numberUseCase);
|
|
44
|
+
}
|
|
45
|
+
catch (e) {
|
|
46
|
+
//
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
expect(useMockedUseCase).toHaveBeenCalledWith(numberUseCase);
|
|
50
|
+
jest.spyOn(useUseCaseModule, 'useUseCase').mockRestore();
|
|
51
|
+
});
|
|
52
|
+
test('should should only return reducers', () => {
|
|
53
|
+
const onChildMount = jest.fn();
|
|
54
|
+
const Child = () => {
|
|
55
|
+
const reducers = useGlobalUseCase(numberUseCase);
|
|
56
|
+
useMount(() => {
|
|
57
|
+
onChildMount(reducers);
|
|
58
|
+
});
|
|
59
|
+
return null;
|
|
60
|
+
};
|
|
61
|
+
const Parent = () => {
|
|
62
|
+
const [, , Provider] = useGlobalUseCase(1, numberUseCase);
|
|
63
|
+
return (_jsx(Provider, { children: _jsx(Child, {}) }));
|
|
64
|
+
};
|
|
65
|
+
render(_jsx(Parent, {}));
|
|
66
|
+
expect(onChildMount).toHaveBeenCalledWith({
|
|
67
|
+
setEntity: expect.any(Function),
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { EntityReducers } from '@mic-rexjs/usecases';
|
|
2
|
+
import { ContextualCoreCollectionHookParameters, RootCoreCollectionHook, RootCoreCollectionHookParameters } from '../useUseCase/types';
|
|
3
|
+
import { ContextualEntityReducers } from '../../configs/defaultUseCaseContext/types';
|
|
4
|
+
export interface GlobalReducersHookParameters<T, TEntityReducers extends EntityReducers<T>> extends ContextualCoreCollectionHookParameters<T, TEntityReducers> {
|
|
5
|
+
}
|
|
6
|
+
export type GlobalReducers<T, TEntityReducers extends EntityReducers<T>> = ContextualEntityReducers<T, TEntityReducers>;
|
|
7
|
+
export interface GlobalReducersHook {
|
|
8
|
+
<T, TEntityReducers extends EntityReducers<T>>(...args: GlobalReducersHookParameters<T, TEntityReducers>): GlobalReducers<T, TEntityReducers>;
|
|
9
|
+
}
|
|
10
|
+
export type GlobalUseCaseHookParameters<T, TEntityReducers extends EntityReducers<T>, TUseCaseOptions extends object = object> = RootCoreCollectionHookParameters<T, TEntityReducers, TUseCaseOptions> | GlobalReducersHookParameters<T, TEntityReducers>;
|
|
11
|
+
export interface GlobalUseCaseHook extends RootCoreCollectionHook, GlobalReducersHook {
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import { UseCaseMappingContext } from '../../configs/usecaseContextMap/types';
|
|
2
1
|
import { EntityReducers } from '@mic-rexjs/usecases';
|
|
3
|
-
import {
|
|
4
|
-
import { ContextualEntityReducers } from '../../configs/defaultUseCaseContext/types';
|
|
2
|
+
import { ChangeCallback, ContextualEntityReducers, UseCaseContext } from '../../configs/defaultUseCaseContext/types';
|
|
5
3
|
import { UseCaseProvider } from './types';
|
|
6
|
-
import {
|
|
7
|
-
export declare const useProvider: <T, TEntityReducers extends EntityReducers<T
|
|
4
|
+
import { UseCaseModes } from '../../enums/UseCaseModes';
|
|
5
|
+
export declare const useProvider: <T, TEntityReducers extends EntityReducers<T>>(context: UseCaseContext<T, TEntityReducers>, mode: UseCaseModes, entity: T, reducers: ContextualEntityReducers<T, TEntityReducers>, changeCallbackCollection: ChangeCallback<T>[]) => UseCaseProvider;
|
|
@@ -1,17 +1,27 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const contextValueRef = useLatest(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
|
+
import { useLatest } from 'ahooks';
|
|
3
|
+
import { UseCaseModes } from '../../enums/UseCaseModes';
|
|
4
|
+
import { useCompareDeps } from '../useCompareDeps';
|
|
5
|
+
import { useConstantFn } from '../useConstantFn';
|
|
6
|
+
export const useProvider = (context, mode, entity, reducers, changeCallbackCollection) => {
|
|
7
|
+
const isGlobal = (mode & UseCaseModes.Global) === UseCaseModes.Global;
|
|
8
|
+
const contextValueRef = useLatest({
|
|
9
|
+
entity,
|
|
10
|
+
reducers,
|
|
11
|
+
changeCallbackCollection,
|
|
12
|
+
});
|
|
13
|
+
const key = useCompareDeps(isGlobal ? [] : [entity, reducers, changeCallbackCollection]);
|
|
14
|
+
const getContextValue = useCallback(() => {
|
|
15
|
+
void key;
|
|
16
|
+
return contextValueRef.current;
|
|
17
|
+
}, [key, contextValueRef]);
|
|
18
|
+
const getContextValueRef = useLatest(getContextValue);
|
|
19
|
+
return useConstantFn(({ children, with: withProviders = [] }) => {
|
|
20
|
+
const { Provider: ContextProvider } = context;
|
|
21
|
+
return React.createElement(ContextProvider, {
|
|
22
|
+
value: getContextValueRef.current,
|
|
23
|
+
}, withProviders.reduceRight((currentChildren, withProvider) => {
|
|
24
|
+
return React.createElement(withProvider, {}, currentChildren);
|
|
25
|
+
}, children));
|
|
16
26
|
});
|
|
17
27
|
};
|
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
export interface
|
|
2
|
+
export interface UseCaseProviderProps {
|
|
3
|
+
children?: React.ReactNode;
|
|
4
|
+
with?: UseCaseProvider[];
|
|
5
|
+
}
|
|
6
|
+
export interface UseCaseProvider extends React.FC<UseCaseProviderProps> {
|
|
3
7
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { useUseCase } from '../useUseCase';
|
|
2
|
+
import { UseCaseModes } from '../../enums/UseCaseModes';
|
|
3
|
+
export const useStatelessUseCase = ((...args) => {
|
|
4
|
+
const [arg1, arg2, ...rest] = args;
|
|
5
|
+
const isContextRoot = typeof arg2 === 'function';
|
|
6
|
+
const coreCollection = useUseCase(...(isContextRoot ? [arg1, arg2, UseCaseModes.Stateless, ...rest] : args));
|
|
7
|
+
return coreCollection;
|
|
8
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { entityUseCase } from '@mic-rexjs/usecases';
|
|
3
|
+
import { describe, expect, jest, test } from '@jest/globals';
|
|
4
|
+
import { UseCaseModes } from '../../enums/UseCaseModes';
|
|
5
|
+
import { render, renderHook } from '@testing-library/react';
|
|
6
|
+
import { useMount } from 'ahooks';
|
|
7
|
+
import * as useUseCaseModule from '../useUseCase';
|
|
8
|
+
import { useStatelessUseCase } from '.';
|
|
9
|
+
const numberUseCase = () => {
|
|
10
|
+
return entityUseCase();
|
|
11
|
+
};
|
|
12
|
+
describe('useStatelessUseCase', () => {
|
|
13
|
+
describe('`useStatelessUseCase` should work the same as `RootCoreCollectionHook`', () => {
|
|
14
|
+
test('should pass `UseCaseModes.Stateless` to `useUseCase`', () => {
|
|
15
|
+
const useMockedUseCase = jest.fn();
|
|
16
|
+
jest.spyOn(useUseCaseModule, 'useUseCase').mockImplementation(useMockedUseCase);
|
|
17
|
+
renderHook(() => {
|
|
18
|
+
useStatelessUseCase(1, numberUseCase);
|
|
19
|
+
});
|
|
20
|
+
expect(useMockedUseCase).toHaveBeenCalledWith(1, numberUseCase, UseCaseModes.Stateless);
|
|
21
|
+
jest.spyOn(useUseCaseModule, 'useUseCase').mockRestore();
|
|
22
|
+
});
|
|
23
|
+
test('should should return `CoreCollection` with Provider', () => {
|
|
24
|
+
const { result } = renderHook(() => {
|
|
25
|
+
return useStatelessUseCase(1, numberUseCase);
|
|
26
|
+
});
|
|
27
|
+
const { current } = result;
|
|
28
|
+
expect(current).toEqual([
|
|
29
|
+
1,
|
|
30
|
+
{
|
|
31
|
+
setEntity: expect.any(Function),
|
|
32
|
+
},
|
|
33
|
+
expect.any(Function),
|
|
34
|
+
]);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
describe('`useStatelessUseCase` should work the same as `ContextualCoreCollectionHook`', () => {
|
|
38
|
+
test('check `useUseCase` has received correct arguments', () => {
|
|
39
|
+
const useMockedUseCase = jest.fn();
|
|
40
|
+
jest.spyOn(useUseCaseModule, 'useUseCase').mockImplementation(useMockedUseCase);
|
|
41
|
+
renderHook(() => {
|
|
42
|
+
try {
|
|
43
|
+
useStatelessUseCase(numberUseCase);
|
|
44
|
+
}
|
|
45
|
+
catch (e) {
|
|
46
|
+
//
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
expect(useMockedUseCase).toHaveBeenCalledWith(numberUseCase);
|
|
50
|
+
jest.spyOn(useUseCaseModule, 'useUseCase').mockRestore();
|
|
51
|
+
});
|
|
52
|
+
test('should should only return reducers', () => {
|
|
53
|
+
const onChildMount = jest.fn();
|
|
54
|
+
const Child = () => {
|
|
55
|
+
const coreCollection = useStatelessUseCase(numberUseCase);
|
|
56
|
+
useMount(() => {
|
|
57
|
+
onChildMount(coreCollection);
|
|
58
|
+
});
|
|
59
|
+
return null;
|
|
60
|
+
};
|
|
61
|
+
const Parent = () => {
|
|
62
|
+
const [, , Provider] = useStatelessUseCase(1, numberUseCase);
|
|
63
|
+
return (_jsx(Provider, { children: _jsx(Child, {}) }));
|
|
64
|
+
};
|
|
65
|
+
render(_jsx(Parent, {}));
|
|
66
|
+
expect(onChildMount).toHaveBeenCalledWith([
|
|
67
|
+
1,
|
|
68
|
+
{
|
|
69
|
+
setEntity: expect.any(Function),
|
|
70
|
+
},
|
|
71
|
+
null,
|
|
72
|
+
]);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
});
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { EntityReducers } from '@mic-rexjs/usecases';
|
|
2
|
+
import { ContextualCoreCollectionHook, ContextualCoreCollectionHookParameters, RootCoreCollectionHook, RootCoreCollectionHookParameters } from '../useUseCase/types';
|
|
3
|
+
export type StatelessUseCaseHookParameters<T, TEntityReducers extends EntityReducers<T>, TUseCaseOptions extends object = object> = RootCoreCollectionHookParameters<T, TEntityReducers, TUseCaseOptions> | ContextualCoreCollectionHookParameters<T, TEntityReducers>;
|
|
4
|
+
export interface StatelessUseCaseHook extends RootCoreCollectionHook, ContextualCoreCollectionHook {
|
|
5
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -5,47 +5,45 @@ import { useConstantFn } from '../useConstantFn';
|
|
|
5
5
|
import { useProvider } from '../useProvider';
|
|
6
6
|
import { useCompareDeps } from '../useCompareDeps';
|
|
7
7
|
import { initEntityReducers } from '../../methods/initEntityReducers';
|
|
8
|
-
import { useOptionsRefCollection } from '../useOptionsRefCollection';
|
|
9
8
|
import { triggerCallbacks } from '../../methods/triggerCallbacks';
|
|
10
9
|
import { getRootEntity } from '../../methods/getRootEntity';
|
|
11
10
|
import { useUseCaseContext } from '../useUseCaseContext';
|
|
12
11
|
import { defaultUseCaseContext } from '../../configs/defaultUseCaseContext';
|
|
13
12
|
import { useIsRenderingRef } from '../useIsRenderingRef';
|
|
14
13
|
import { cacheReducerCalls } from '../../methods/cacheReducerCalls';
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const [
|
|
20
|
-
const
|
|
14
|
+
import { UseCaseModes } from '../../enums/UseCaseModes';
|
|
15
|
+
import { toMaxArguments } from '../../methods/toMaxArguments';
|
|
16
|
+
import { useChangeCallbackCollection } from '../useChangeCallbackCollection';
|
|
17
|
+
export const useUseCase = ((...args) => {
|
|
18
|
+
const [unsafeEntity, unsafeUsecase, unsafeMode, options, deps] = toMaxArguments(args);
|
|
19
|
+
const [entityState, setEntityState] = useState(unsafeEntity);
|
|
20
|
+
const usecase = useConstantFn(unsafeUsecase);
|
|
21
|
+
const entityUseCase = usecase;
|
|
22
|
+
const mode = useConstant(unsafeMode);
|
|
21
23
|
const depsKey = useCompareDeps(deps);
|
|
22
24
|
const isRenderingRef = useIsRenderingRef();
|
|
23
|
-
const
|
|
24
|
-
? arg2
|
|
25
|
-
: arg1);
|
|
26
|
-
const entityUseCase = usecase;
|
|
25
|
+
const isContextRoot = useConstant(typeof args[1] === 'function');
|
|
27
26
|
const defaultContext = defaultUseCaseContext;
|
|
28
|
-
const context = useUseCaseContext(entityUseCase,
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
const
|
|
27
|
+
const context = useUseCaseContext(entityUseCase, isContextRoot ? null : defaultContext);
|
|
28
|
+
const getContextValue = useContext(context);
|
|
29
|
+
const hasContextValueGetter = getContextValue !== null;
|
|
30
|
+
const { entity: contextEntity, reducers: contextEntityReducers = null, changeCallbackCollection: contextChangeCallbackCollection = null, } = getContextValue?.() || {};
|
|
32
31
|
// 是否需要初始化根 `redurcers`
|
|
33
|
-
const isRoot =
|
|
32
|
+
const isRoot = isContextRoot || !hasContextValueGetter;
|
|
34
33
|
// 是否为上下文模式
|
|
35
|
-
const isContextMode =
|
|
36
|
-
|
|
37
|
-
const optionsRefCollection = useOptionsRefCollection(isRoot, contextOptionsRefCollection || null, options);
|
|
34
|
+
const isContextMode = isContextRoot || hasContextValueGetter;
|
|
35
|
+
const changeCallbackCollection = useChangeCallbackCollection(isRoot, contextChangeCallbackCollection, options);
|
|
38
36
|
const entity = useCreation(() => {
|
|
39
|
-
if (!
|
|
37
|
+
if (!isContextRoot) {
|
|
40
38
|
return contextEntity;
|
|
41
39
|
}
|
|
42
|
-
return getRootEntity(entityState,
|
|
43
|
-
}, [
|
|
40
|
+
return getRootEntity(entityState, unsafeEntity, mode);
|
|
41
|
+
}, [isContextRoot, contextEntity, mode, entityState, unsafeEntity]);
|
|
44
42
|
const onEntityChange = useMemoizedFn((newEntity, oldEntity) => {
|
|
45
|
-
if (
|
|
43
|
+
if ((mode & UseCaseModes.Stateless) !== UseCaseModes.Stateless) {
|
|
46
44
|
setEntityState(newEntity);
|
|
47
45
|
}
|
|
48
|
-
triggerCallbacks(
|
|
46
|
+
triggerCallbacks(changeCallbackCollection, newEntity, oldEntity);
|
|
49
47
|
});
|
|
50
48
|
const createRootEntityReducers = useMemoizedFn(() => {
|
|
51
49
|
const initOptions = options;
|
|
@@ -56,11 +54,11 @@ export const useUseCase = (arg1, arg2, arg3, arg4) => {
|
|
|
56
54
|
});
|
|
57
55
|
const rootEntityReducers = useCreation(() => {
|
|
58
56
|
void depsKey;
|
|
59
|
-
if (!
|
|
57
|
+
if (!isContextRoot) {
|
|
60
58
|
return null;
|
|
61
59
|
}
|
|
62
60
|
return createRootEntityReducers();
|
|
63
|
-
}, [
|
|
61
|
+
}, [isContextRoot, depsKey, createRootEntityReducers]);
|
|
64
62
|
const entityReducers = useCreation(() => {
|
|
65
63
|
return rootEntityReducers || contextEntityReducers || {};
|
|
66
64
|
}, [rootEntityReducers, contextEntityReducers]);
|
|
@@ -71,14 +69,14 @@ export const useUseCase = (arg1, arg2, arg3, arg4) => {
|
|
|
71
69
|
}
|
|
72
70
|
return createReducers();
|
|
73
71
|
}, [isContextMode, depsKey, createReducers]);
|
|
74
|
-
const Provider = useProvider(context, entity, entityReducers,
|
|
72
|
+
const Provider = useProvider(context, mode, entity, entityReducers, changeCallbackCollection);
|
|
75
73
|
const createCoreCollection = useMemoizedFn((coreEntity, coreReducers) => {
|
|
76
74
|
return [
|
|
77
75
|
coreEntity,
|
|
78
76
|
cacheReducerCalls(coreReducers, () => {
|
|
79
77
|
return isRenderingRef.current;
|
|
80
78
|
}),
|
|
81
|
-
|
|
79
|
+
isContextRoot ? Provider : null,
|
|
82
80
|
];
|
|
83
81
|
});
|
|
84
82
|
return useCreation(() => {
|
|
@@ -87,4 +85,4 @@ export const useUseCase = (arg1, arg2, arg3, arg4) => {
|
|
|
87
85
|
}
|
|
88
86
|
return reducers;
|
|
89
87
|
}, [isContextMode, entity, entityReducers, reducers, createCoreCollection]);
|
|
90
|
-
};
|
|
88
|
+
});
|