@mic-rexjs/usecases-react 2.6.3 → 2.7.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/dist/index.min.js +1 -1
- package/es/components/UseCaseFragment/index.d.ts +2 -2
- package/es/components/UseCaseFragment/types.d.ts +3 -3
- package/es/enums/ArgumentTypes/index.d.ts +6 -0
- package/es/enums/ArgumentTypes/index.js +7 -0
- package/es/enums/Statuses/index.d.ts +27 -0
- package/es/enums/Statuses/index.js +28 -0
- package/es/hooks/useArgumentTypes/index.d.ts +2 -2
- package/es/hooks/useArgumentTypes/index.js +9 -4
- package/es/hooks/useContext/index.d.ts +5 -0
- package/es/hooks/useContext/index.js +14 -0
- package/es/hooks/useContext/index.test.js +52 -0
- package/es/hooks/useContextUseCase/index.d.ts +2 -0
- package/es/hooks/useContextUseCase/index.js +7 -0
- package/es/hooks/useContextValue/index.d.ts +4 -0
- package/es/hooks/useContextValue/index.js +13 -0
- package/es/hooks/useContextualItem/index.d.ts +2 -2
- package/es/hooks/useContextualItem/index.js +2 -2
- package/es/hooks/useEntity/index.d.ts +2 -2
- package/es/hooks/useEntity/index.js +20 -20
- package/es/hooks/useFullArguments/index.d.ts +5 -0
- package/es/hooks/useFullArguments/index.js +22 -0
- package/es/{methods/fillArguments → hooks/useFullArguments}/types.d.ts +3 -2
- package/es/hooks/useProvider/index.d.ts +5 -4
- package/es/hooks/useProvider/index.js +7 -14
- package/es/hooks/useRuntimeEntity/index.d.ts +2 -2
- package/es/hooks/useRuntimeEntity/index.js +9 -9
- package/es/hooks/useStatuses/index.d.ts +5 -0
- package/es/hooks/useStatuses/index.js +27 -0
- package/es/hooks/useUseCase/index.js +13 -13
- package/es/hooks/useUseCase/index.test.js +106 -1
- package/es/hooks/useUseCase/types.d.ts +9 -9
- package/es/index.d.ts +1 -0
- package/es/index.js +1 -0
- package/es/methods/initEntityReducers/index.d.ts +4 -3
- package/es/methods/registerGlobalUseCase/index.d.ts +1 -0
- package/es/methods/registerGlobalUseCase/index.js +2 -0
- package/es/usecases/contextUseCase/index.d.ts +2 -2
- package/es/usecases/contextUseCase/index.js +99 -18
- package/es/usecases/contextUseCase/types.d.ts +33 -2
- package/lib/enums/ArgumentTypes/index.js +13 -0
- package/lib/enums/Statuses/index.js +34 -0
- package/lib/hooks/useArgumentTypes/index.js +9 -3
- package/lib/hooks/useContext/index.js +23 -0
- package/lib/hooks/useContext/index.test.js +62 -0
- package/lib/hooks/useContextUseCase/index.js +13 -0
- package/lib/hooks/useContextValue/index.js +20 -0
- package/lib/hooks/useContextualItem/index.js +2 -2
- package/lib/hooks/useEntity/index.js +21 -21
- package/lib/hooks/useFullArguments/index.js +25 -0
- package/lib/hooks/useProvider/index.js +8 -15
- package/lib/hooks/useRuntimeEntity/index.js +9 -9
- package/lib/hooks/useStatuses/index.js +33 -0
- package/lib/hooks/useUseCase/index.js +13 -13
- package/lib/hooks/useUseCase/index.test.js +152 -7
- package/lib/index.js +8 -1
- package/lib/methods/registerGlobalUseCase/index.js +9 -0
- package/lib/usecases/contextUseCase/index.js +103 -20
- package/package.json +3 -3
- package/es/configs/defaultUseCaseContext/index.d.ts +0 -4
- package/es/configs/defaultUseCaseContext/index.js +0 -2
- package/es/configs/defaultUseCaseContext/types.d.ts +0 -19
- package/es/configs/useCaseContextReferenceMap/index.d.ts +0 -1
- package/es/configs/useCaseContextReferenceMap/index.js +0 -1
- package/es/configs/useCaseContextReferenceMap/types.d.ts +0 -8
- package/es/configs/useCaseContextReferenceMap/types.js +0 -1
- package/es/enums/UseCaseArgumentTypes/index.d.ts +0 -4
- package/es/enums/UseCaseArgumentTypes/index.js +0 -5
- package/es/enums/UseCaseStatuses/index.d.ts +0 -8
- package/es/enums/UseCaseStatuses/index.js +0 -14
- package/es/hooks/useUseCaseContext/index.d.ts +0 -4
- package/es/hooks/useUseCaseContext/index.js +0 -48
- package/es/hooks/useUseCaseContext/index.test.js +0 -59
- package/es/hooks/useUseCaseStatuses/index.d.ts +0 -5
- package/es/hooks/useUseCaseStatuses/index.js +0 -22
- package/es/methods/fillArguments/index.d.ts +0 -5
- package/es/methods/fillArguments/index.js +0 -14
- package/es/methods/fillArguments/types.js +0 -1
- package/lib/configs/defaultUseCaseContext/index.js +0 -8
- package/lib/configs/useCaseContextReferenceMap/index.js +0 -7
- package/lib/configs/useCaseContextReferenceMap/types.js +0 -5
- package/lib/enums/UseCaseArgumentTypes/index.js +0 -11
- package/lib/enums/UseCaseStatuses/index.js +0 -20
- package/lib/hooks/useUseCaseContext/index.js +0 -57
- package/lib/hooks/useUseCaseContext/index.test.js +0 -73
- package/lib/hooks/useUseCaseStatuses/index.js +0 -28
- package/lib/methods/fillArguments/index.js +0 -21
- package/lib/methods/fillArguments/types.js +0 -5
- /package/es/hooks/{useUseCaseContext → useContext}/index.test.d.ts +0 -0
- /package/es/{configs/defaultUseCaseContext → hooks/useFullArguments}/types.js +0 -0
- /package/lib/{configs/defaultUseCaseContext → hooks/useFullArguments}/types.js +0 -0
|
@@ -5,6 +5,7 @@ import { renderHook, act, render, fireEvent, screen } from '@testing-library/rea
|
|
|
5
5
|
import { useUseCase } from '.';
|
|
6
6
|
import { useDeepCompareEffect, useMemoizedFn, useMount, useUpdate, useUpdateEffect } from 'ahooks';
|
|
7
7
|
import { Fragment, useEffect, useRef, useState } from 'react';
|
|
8
|
+
import { registerGlobalUseCase } from '../../methods/registerGlobalUseCase';
|
|
8
9
|
const EXT_1 = '.png';
|
|
9
10
|
const EXT_2 = '.jpg';
|
|
10
11
|
const PATH_1 = `hello${EXT_1}`;
|
|
@@ -1104,7 +1105,7 @@ describe('useUseCase', () => {
|
|
|
1104
1105
|
expect(onBooleanMount).toHaveBeenCalledWith(true);
|
|
1105
1106
|
});
|
|
1106
1107
|
});
|
|
1107
|
-
describe('`useUseCase` should work the same as useContextualCoreCollection', () => {
|
|
1108
|
+
describe('`useUseCase` should work the same as `useContextualCoreCollection`', () => {
|
|
1108
1109
|
test('Should trigger Parent & Child to update', () => {
|
|
1109
1110
|
const onParentUpdate = jest.fn();
|
|
1110
1111
|
const onChildUpdate = jest.fn();
|
|
@@ -1433,6 +1434,110 @@ describe('useUseCase', () => {
|
|
|
1433
1434
|
oldValue: EXT_1,
|
|
1434
1435
|
});
|
|
1435
1436
|
});
|
|
1437
|
+
test('global usecase should share the entity to any components', () => {
|
|
1438
|
+
const onValue = jest.fn();
|
|
1439
|
+
const firstButtonText = 'first button';
|
|
1440
|
+
const secondButtonText = 'second button';
|
|
1441
|
+
const numberUseCase = () => {
|
|
1442
|
+
return entityUseCase();
|
|
1443
|
+
};
|
|
1444
|
+
const A = () => {
|
|
1445
|
+
const [entity, { setEntity }] = useUseCase(numberUseCase);
|
|
1446
|
+
const onButtonClick = () => {
|
|
1447
|
+
setEntity(2);
|
|
1448
|
+
};
|
|
1449
|
+
useMount(() => {
|
|
1450
|
+
onValue(entity);
|
|
1451
|
+
});
|
|
1452
|
+
return (_jsx("div", { children: _jsx("button", { onClick: onButtonClick, children: firstButtonText }) }));
|
|
1453
|
+
};
|
|
1454
|
+
const B = () => {
|
|
1455
|
+
const [entity, { setEntity }] = useUseCase(numberUseCase);
|
|
1456
|
+
const onButtonClick = () => {
|
|
1457
|
+
setEntity(3);
|
|
1458
|
+
};
|
|
1459
|
+
useMount(() => {
|
|
1460
|
+
onValue(entity);
|
|
1461
|
+
});
|
|
1462
|
+
return (_jsx("div", { children: _jsx("button", { onClick: onButtonClick, children: secondButtonText }) }));
|
|
1463
|
+
};
|
|
1464
|
+
registerGlobalUseCase(1, numberUseCase);
|
|
1465
|
+
render(_jsx(A, {}));
|
|
1466
|
+
expect(onValue).toHaveBeenNthCalledWith(1, 1);
|
|
1467
|
+
fireEvent.click(screen.getByText(firstButtonText));
|
|
1468
|
+
render(_jsx(B, {}));
|
|
1469
|
+
expect(onValue).toHaveBeenNthCalledWith(2, 2);
|
|
1470
|
+
fireEvent.click(screen.getByText(secondButtonText));
|
|
1471
|
+
});
|
|
1472
|
+
test('global usecase should trigger `onChange` in any components when entity has changed', () => {
|
|
1473
|
+
const onValueChange1 = jest.fn();
|
|
1474
|
+
const onValueChange2 = jest.fn();
|
|
1475
|
+
const firstButtonText = 'first button';
|
|
1476
|
+
const secondButtonText = 'second button';
|
|
1477
|
+
const numberUseCase = () => {
|
|
1478
|
+
return entityUseCase();
|
|
1479
|
+
};
|
|
1480
|
+
const A = () => {
|
|
1481
|
+
const [, { setEntity }] = useUseCase(numberUseCase, {
|
|
1482
|
+
onChange(value) {
|
|
1483
|
+
onValueChange1(value);
|
|
1484
|
+
},
|
|
1485
|
+
});
|
|
1486
|
+
const onButtonClick = () => {
|
|
1487
|
+
setEntity(2);
|
|
1488
|
+
};
|
|
1489
|
+
return (_jsx("div", { children: _jsx("button", { onClick: onButtonClick, children: firstButtonText }) }));
|
|
1490
|
+
};
|
|
1491
|
+
const B = () => {
|
|
1492
|
+
const [, { setEntity }] = useUseCase(numberUseCase, {
|
|
1493
|
+
onChange(value) {
|
|
1494
|
+
onValueChange2(value);
|
|
1495
|
+
},
|
|
1496
|
+
});
|
|
1497
|
+
const onButtonClick = () => {
|
|
1498
|
+
setEntity(3);
|
|
1499
|
+
};
|
|
1500
|
+
return (_jsx("div", { children: _jsx("button", { onClick: onButtonClick, children: secondButtonText }) }));
|
|
1501
|
+
};
|
|
1502
|
+
registerGlobalUseCase(1, numberUseCase);
|
|
1503
|
+
render(_jsx(A, {}));
|
|
1504
|
+
fireEvent.click(screen.getByText(firstButtonText));
|
|
1505
|
+
expect(onValueChange1).toHaveBeenNthCalledWith(1, 2);
|
|
1506
|
+
render(_jsx(B, {}));
|
|
1507
|
+
fireEvent.click(screen.getByText(secondButtonText));
|
|
1508
|
+
expect(onValueChange1).toHaveBeenNthCalledWith(2, 3);
|
|
1509
|
+
expect(onValueChange2).toHaveBeenNthCalledWith(1, 3);
|
|
1510
|
+
});
|
|
1511
|
+
test('global usecase should trigger update for components when entity has changed', () => {
|
|
1512
|
+
const onUpdate1 = jest.fn();
|
|
1513
|
+
const onUpdate2 = jest.fn();
|
|
1514
|
+
const buttonText = 'my button';
|
|
1515
|
+
const numberUseCase = () => {
|
|
1516
|
+
return entityUseCase();
|
|
1517
|
+
};
|
|
1518
|
+
const A = () => {
|
|
1519
|
+
const [entity, { setEntity }] = useUseCase(numberUseCase);
|
|
1520
|
+
const onButtonClick = () => {
|
|
1521
|
+
setEntity(6);
|
|
1522
|
+
};
|
|
1523
|
+
useUpdateEffect(() => {
|
|
1524
|
+
onUpdate1(entity);
|
|
1525
|
+
}, [entity]);
|
|
1526
|
+
return (_jsx("div", { children: _jsx("button", { onClick: onButtonClick, children: buttonText }) }));
|
|
1527
|
+
};
|
|
1528
|
+
const B = () => {
|
|
1529
|
+
const [entity] = useUseCase(numberUseCase);
|
|
1530
|
+
useUpdateEffect(() => {
|
|
1531
|
+
onUpdate2(entity);
|
|
1532
|
+
}, [entity]);
|
|
1533
|
+
return _jsx(A, {});
|
|
1534
|
+
};
|
|
1535
|
+
registerGlobalUseCase(1, numberUseCase);
|
|
1536
|
+
render(_jsx(B, {}));
|
|
1537
|
+
fireEvent.click(screen.getByText(buttonText));
|
|
1538
|
+
expect(onUpdate1).toHaveBeenNthCalledWith(1, 6);
|
|
1539
|
+
expect(onUpdate2).toHaveBeenNthCalledWith(1, 6);
|
|
1540
|
+
});
|
|
1436
1541
|
});
|
|
1437
1542
|
describe('`useUseCase` should work the same as `useReducers`', () => {
|
|
1438
1543
|
test('`entity` should equal `defaultFile`', () => {
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { UseCase } from '@mic-rexjs/usecases';
|
|
2
2
|
import { UseCaseProvider } from '../useProvider/types';
|
|
3
|
-
import { ContextualEntityReducers } from '../../
|
|
4
|
-
import { SymbolSet, SymbolSetTarget } from '@mic-rexjs/usecases/es/types';
|
|
3
|
+
import { ContextualEntityReducers } from '../../usecases/contextUseCase/types';
|
|
4
|
+
import { EntityReducerMap, EntityReducers, InferableEntityUseCase, ReducerMap, SymbolSet, SymbolSetTarget } from '@mic-rexjs/usecases/es/types';
|
|
5
5
|
export interface NonEntitySymbolSet extends SymbolSet {
|
|
6
6
|
entity?: never;
|
|
7
7
|
}
|
|
8
|
-
export type RootCoreCollection<T, TEntityReducers extends
|
|
8
|
+
export type RootCoreCollection<T, TEntityReducers extends EntityReducerMap<T>> = [
|
|
9
9
|
entity: T,
|
|
10
10
|
reducers: ContextualEntityReducers<T, TEntityReducers>,
|
|
11
11
|
Provider: UseCaseProvider
|
|
12
12
|
];
|
|
13
|
-
export type ContextualCoreCollection<T, TEntityReducers extends
|
|
13
|
+
export type ContextualCoreCollection<T, TEntityReducers extends EntityReducerMap<T>> = [
|
|
14
14
|
entity: T,
|
|
15
15
|
reducers: ContextualEntityReducers<T, TEntityReducers>
|
|
16
16
|
];
|
|
17
|
-
export type CoreCollection<T, TEntityReducers extends
|
|
17
|
+
export type CoreCollection<T, TEntityReducers extends EntityReducerMap<T>> = RootCoreCollection<T, TEntityReducers> | ContextualCoreCollection<T, TEntityReducers>;
|
|
18
18
|
export interface EntityGetter<T> {
|
|
19
19
|
(): T;
|
|
20
20
|
}
|
|
@@ -47,13 +47,13 @@ export interface UseCaseHookOwnOptions<T, TUseCaseOptions extends object> extend
|
|
|
47
47
|
}
|
|
48
48
|
export type UseCaseHookOptions<T, TUseCaseOptions extends object = object> = TUseCaseOptions & UseCaseHookOwnOptions<T, TUseCaseOptions>;
|
|
49
49
|
export interface ReducersHook {
|
|
50
|
-
<T extends
|
|
50
|
+
<T extends ReducerMap, TUseCaseOptions extends object = object>(usecase: UseCase<T & SymbolSetTarget<NonEntitySymbolSet>, TUseCaseOptions>, options?: TUseCaseOptions, deps?: unknown[]): T;
|
|
51
51
|
}
|
|
52
52
|
export interface ContextualCoreCollectionHook {
|
|
53
|
-
<T, TEntityReducers extends EntityReducers<T>>(usecase:
|
|
53
|
+
<T, TEntityReducers extends EntityReducers<T>>(usecase: InferableEntityUseCase<T, TEntityReducers>, options?: UseCaseHookContextualOptions<T>, deps?: unknown[]): ContextualCoreCollection<T, TEntityReducers>;
|
|
54
54
|
}
|
|
55
55
|
export interface RootCoreCollectionHook {
|
|
56
|
-
<T, TEntityReducers extends
|
|
56
|
+
<T, TEntityReducers extends EntityReducerMap<T>, TUseCaseOptions extends object = object>(entity: T | EntityGetter<T>, usecase: InferableEntityUseCase<T, TEntityReducers & EntityReducers<T>, TUseCaseOptions>, options?: UseCaseHookOptions<T, TUseCaseOptions>, deps?: unknown[]): RootCoreCollection<T, EntityReducers<T, TEntityReducers>>;
|
|
57
57
|
}
|
|
58
58
|
export interface CoreCollectionHook extends ContextualCoreCollectionHook, RootCoreCollectionHook {
|
|
59
59
|
}
|
package/es/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { UseCaseFragment } from './components/UseCaseFragment';
|
|
2
2
|
export { useUseCase } from './hooks/useUseCase';
|
|
3
|
+
export { registerGlobalUseCase } from './methods/registerGlobalUseCase';
|
|
3
4
|
export type { EntityWatchEvent, RootCoreCollection, ContextualCoreCollection, CoreCollection, } from './hooks/useUseCase/types';
|
|
4
5
|
export type { UseCaseHookOptions } from './hooks/useUseCase/types';
|
|
5
6
|
export type { UseCaseProvider } from './hooks/useProvider/types';
|
package/es/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EntityStore } from '@mic-rexjs/usecases';
|
|
2
2
|
import { UseCaseHookOptions } from '../../hooks/useUseCase/types';
|
|
3
|
-
import { ContextualEntityReducers } from '../../
|
|
4
|
-
|
|
3
|
+
import { ContextualEntityReducers } from '../../usecases/contextUseCase/types';
|
|
4
|
+
import { EntityReducerMap, InferableEntityUseCase } from '@mic-rexjs/usecases/es/types';
|
|
5
|
+
export declare const initEntityReducers: <T, TEntityReducers extends EntityReducerMap<T>, TUseCaseOptions extends object = object>(usecase: InferableEntityUseCase<T, TEntityReducers, TUseCaseOptions>, store: EntityStore<T>, options: UseCaseHookOptions<T, TUseCaseOptions>) => ContextualEntityReducers<T, TEntityReducers>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const registerGlobalUseCase: <T>(entity: T, usecase: import("@mic-rexjs/usecases/es/types").InferableEntityUseCase<T>) => void;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare const contextUseCase:
|
|
1
|
+
import { ContextUseCase } from './types';
|
|
2
|
+
export declare const contextUseCase: ContextUseCase;
|
|
@@ -1,19 +1,100 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
import { createUseCase, EntityStore } from '@mic-rexjs/usecases';
|
|
2
|
+
import { ArgumentTypes } from '../../enums/ArgumentTypes';
|
|
3
|
+
import { createContext } from 'react';
|
|
4
|
+
import { Statuses } from '../../enums/Statuses';
|
|
5
|
+
import { initEntityReducers } from '../../methods/initEntityReducers';
|
|
6
|
+
export const contextUseCase = createUseCase(() => {
|
|
7
|
+
const referenceMap = new Map();
|
|
8
|
+
const globalContextMap = new Map();
|
|
9
|
+
const globalContextValueMap = new Map();
|
|
10
|
+
const defaultUseCaseContext = createContext(null);
|
|
11
|
+
return () => {
|
|
12
|
+
const createContextValue = (store, reducers, statuses) => {
|
|
13
|
+
if ((statuses & Statuses.EntityEnabled) === Statuses.EntityEnabled) {
|
|
14
|
+
return {
|
|
15
|
+
store,
|
|
16
|
+
reducers,
|
|
17
|
+
statuses,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
return { reducers, statuses };
|
|
21
|
+
};
|
|
22
|
+
const getGlobalContextValue = (key) => {
|
|
23
|
+
const context = typeof key === 'function' ? globalContextMap.get(key) : key;
|
|
24
|
+
return globalContextValueMap.get(context) || null;
|
|
25
|
+
};
|
|
26
|
+
const isGlobal = (usecase) => {
|
|
27
|
+
return globalContextMap.has(usecase);
|
|
28
|
+
};
|
|
29
|
+
const registerUseCase = (usecase, argumentTypes) => {
|
|
30
|
+
if (referenceMap.has(usecase)) {
|
|
31
|
+
const reference = referenceMap.get(usecase);
|
|
32
|
+
const { value, times } = reference;
|
|
33
|
+
referenceMap.set(usecase, {
|
|
34
|
+
value,
|
|
35
|
+
times: times + 1,
|
|
36
|
+
});
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
if ((argumentTypes & ArgumentTypes.Entity) !== ArgumentTypes.Entity) {
|
|
40
|
+
return defaultUseCaseContext;
|
|
41
|
+
}
|
|
42
|
+
const context = createContext(null);
|
|
43
|
+
referenceMap.set(usecase, {
|
|
44
|
+
value: context,
|
|
45
|
+
times: 1,
|
|
46
|
+
});
|
|
47
|
+
return context;
|
|
48
|
+
};
|
|
49
|
+
const unregisterUseCase = (usecase, argumentTypes) => {
|
|
50
|
+
if ((argumentTypes & ArgumentTypes.Entity) !== ArgumentTypes.Entity) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
if (!referenceMap.has(usecase)) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
const reference = referenceMap.get(usecase);
|
|
57
|
+
const { value, times } = reference;
|
|
58
|
+
if (times === 1) {
|
|
59
|
+
referenceMap.delete(usecase);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
referenceMap.set(usecase, {
|
|
63
|
+
value,
|
|
64
|
+
times: times - 1,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return true;
|
|
68
|
+
};
|
|
69
|
+
const registerGlobalUseCase = (entity, usecase) => {
|
|
70
|
+
if (globalContextMap.has(usecase)) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const store = new EntityStore(entity);
|
|
74
|
+
const reducers = initEntityReducers(usecase, store, {});
|
|
75
|
+
const contextValue = createContextValue(store, reducers, Statuses.GlobalEnabled);
|
|
76
|
+
const context = registerUseCase(usecase, ArgumentTypes.GlobalEntity);
|
|
77
|
+
globalContextMap.set(usecase, context);
|
|
78
|
+
globalContextValueMap.set(context, contextValue);
|
|
79
|
+
};
|
|
80
|
+
const unregisterGlobalUseCase = (usecase) => {
|
|
81
|
+
if (!globalContextMap.has(usecase)) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
const context = globalContextMap.get(usecase);
|
|
85
|
+
globalContextMap.delete(usecase);
|
|
86
|
+
globalContextValueMap.delete(context);
|
|
87
|
+
referenceMap.delete(usecase);
|
|
88
|
+
return true;
|
|
89
|
+
};
|
|
90
|
+
return {
|
|
91
|
+
createContextValue,
|
|
92
|
+
getGlobalContextValue,
|
|
93
|
+
isGlobal,
|
|
94
|
+
registerUseCase,
|
|
95
|
+
registerGlobalUseCase,
|
|
96
|
+
unregisterUseCase,
|
|
97
|
+
unregisterGlobalUseCase,
|
|
98
|
+
};
|
|
15
99
|
};
|
|
16
|
-
|
|
17
|
-
hasContext,
|
|
18
|
-
};
|
|
19
|
-
};
|
|
100
|
+
});
|
|
@@ -1,4 +1,35 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { ArgumentTypes } from '../../enums/ArgumentTypes';
|
|
3
|
+
import { Statuses } from '../../enums/Statuses';
|
|
4
|
+
import { AsyncEntityGenerator, EntityGenerator, EntityReducer, EntityStore, ReducerKeys, Reducers } from '@mic-rexjs/usecases';
|
|
5
|
+
import { EntityReducerMap, InferableEntityUseCase, InferableUseCase, ReducerMap } from '@mic-rexjs/usecases/es/types';
|
|
6
|
+
export type ContextualEntityReducer<T, TEntityReducer extends EntityReducer<T>> = TEntityReducer extends (entity: infer TEntity, ...args: infer TArgs) => infer TReturn ? (...args: TArgs) => TReturn extends AsyncEntityGenerator<TEntity, infer TResult> ? Promise<TResult> : TReturn extends EntityGenerator<TEntity, infer TResult> ? TResult : TReturn : never;
|
|
7
|
+
export type ContextualEntityReducers<T, TEntityReducers extends EntityReducerMap<T>> = {
|
|
8
|
+
[K in ReducerKeys<TEntityReducers>]: ContextualEntityReducer<T, TEntityReducers[K]>;
|
|
9
|
+
};
|
|
10
|
+
export interface ContextValue<T extends ReducerMap> {
|
|
11
|
+
reducers: T;
|
|
12
|
+
statuses: Statuses;
|
|
13
|
+
}
|
|
14
|
+
export interface EntityContextValue<T, TEntityReducers extends EntityReducerMap<T>> extends ContextValue<ContextualEntityReducers<T, TEntityReducers>> {
|
|
15
|
+
store: EntityStore<T>;
|
|
16
|
+
}
|
|
17
|
+
export interface Context<T> extends React.Context<T | null> {
|
|
18
|
+
}
|
|
19
|
+
export interface ContextReference<T> {
|
|
20
|
+
value: Context<T>;
|
|
21
|
+
times: number;
|
|
22
|
+
}
|
|
2
23
|
export type ContextReducers = Reducers<{
|
|
3
|
-
|
|
24
|
+
createContextValue<T, TReducers extends ReducerMap>(store: EntityStore<T>, reducers: TReducers, statuses: Statuses): ContextValue<TReducers>;
|
|
25
|
+
getGlobalContextValue<T, TEntityReducers extends EntityReducerMap<T>, TContextValue extends ContextValue<TEntityReducers> = ContextValue<TEntityReducers>>(key: Context<TContextValue>): TContextValue;
|
|
26
|
+
getGlobalContextValue<T, TEntityReducers extends EntityReducerMap<T>>(usecase: InferableEntityUseCase<T, TEntityReducers>): ContextValue<TEntityReducers> | null;
|
|
27
|
+
isGlobal<T>(usecase: InferableEntityUseCase<T>): boolean;
|
|
28
|
+
registerUseCase<T extends ReducerMap, TUseCaseOptions extends object, TContext extends Context<ContextValue<T>> = Context<ContextValue<T>>>(usecase: InferableUseCase<T, TUseCaseOptions>, argumentTypes: ArgumentTypes): TContext;
|
|
29
|
+
unregisterUseCase<T extends ReducerMap, TUseCaseOptions extends object>(usecase: InferableUseCase<T, TUseCaseOptions>, argumentTypes: ArgumentTypes): boolean;
|
|
30
|
+
registerGlobalUseCase<T>(entity: T, usecase: InferableEntityUseCase<T>): void;
|
|
31
|
+
unregisterGlobalUseCase<T>(usecase: InferableEntityUseCase<T>): boolean;
|
|
4
32
|
}>;
|
|
33
|
+
export interface ContextUseCase {
|
|
34
|
+
(): ContextReducers;
|
|
35
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ArgumentTypes = void 0;
|
|
7
|
+
var ArgumentTypes;
|
|
8
|
+
(function (ArgumentTypes) {
|
|
9
|
+
ArgumentTypes[ArgumentTypes["None"] = 0] = "None";
|
|
10
|
+
ArgumentTypes[ArgumentTypes["Entity"] = 2] = "Entity";
|
|
11
|
+
ArgumentTypes[ArgumentTypes["Global"] = 4] = "Global";
|
|
12
|
+
ArgumentTypes[ArgumentTypes["GlobalEntity"] = 6] = "GlobalEntity";
|
|
13
|
+
})(ArgumentTypes || (exports.ArgumentTypes = ArgumentTypes = {}));
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Statuses = void 0;
|
|
7
|
+
var Statuses;
|
|
8
|
+
(function (Statuses) {
|
|
9
|
+
Statuses[Statuses["None"] = 0] = "None";
|
|
10
|
+
/**
|
|
11
|
+
* 是否需要初始化根 `redurcers`
|
|
12
|
+
*/
|
|
13
|
+
Statuses[Statuses["RootEnabled"] = 2] = "RootEnabled";
|
|
14
|
+
/**
|
|
15
|
+
* 是否为上下文模式
|
|
16
|
+
*/
|
|
17
|
+
Statuses[Statuses["ContextEnabled"] = 4] = "ContextEnabled";
|
|
18
|
+
/**
|
|
19
|
+
* 是否有 `entity`
|
|
20
|
+
*/
|
|
21
|
+
Statuses[Statuses["EntityEnabled"] = 8] = "EntityEnabled";
|
|
22
|
+
/**
|
|
23
|
+
* 是否为全局模式
|
|
24
|
+
*/
|
|
25
|
+
Statuses[Statuses["GlobalEnabled"] = 28] = "GlobalEnabled";
|
|
26
|
+
/**
|
|
27
|
+
* 是否为需要提供 `Provider` 去挂载根 `context`
|
|
28
|
+
*/
|
|
29
|
+
Statuses[Statuses["ContextRootEnabled"] = 6] = "ContextRootEnabled";
|
|
30
|
+
/**
|
|
31
|
+
* 是否初始化与 `entity` 相关的 `reducers`
|
|
32
|
+
*/
|
|
33
|
+
Statuses[Statuses["EntityRootEnabled"] = 14] = "EntityRootEnabled";
|
|
34
|
+
})(Statuses || (exports.Statuses = Statuses = {}));
|
|
@@ -7,16 +7,22 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
exports.useArgumentTypes = void 0;
|
|
8
8
|
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
|
|
9
9
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
10
|
-
var
|
|
10
|
+
var _ArgumentTypes = require("../../enums/ArgumentTypes");
|
|
11
11
|
var _useConstant = require("../useConstant");
|
|
12
|
+
var _useContextUseCase2 = require("../useContextUseCase");
|
|
12
13
|
var useArgumentTypes = exports.useArgumentTypes = function useArgumentTypes(args) {
|
|
14
|
+
var _useContextUseCase = (0, _useContextUseCase2.useContextUseCase)(),
|
|
15
|
+
isGlobal = _useContextUseCase.isGlobal;
|
|
13
16
|
return (0, _useConstant.useConstant)(function () {
|
|
14
|
-
var types =
|
|
17
|
+
var types = _ArgumentTypes.ArgumentTypes.None;
|
|
15
18
|
var _args = (0, _slicedToArray2["default"])(args, 2),
|
|
19
|
+
arg1 = _args[0],
|
|
16
20
|
arg2 = _args[1];
|
|
17
21
|
var type2 = (0, _typeof2["default"])(arg2);
|
|
18
22
|
if (type2 === 'function') {
|
|
19
|
-
types |=
|
|
23
|
+
types |= _ArgumentTypes.ArgumentTypes.Entity;
|
|
24
|
+
} else if (isGlobal(arg1)) {
|
|
25
|
+
types |= _ArgumentTypes.ArgumentTypes.Global;
|
|
20
26
|
}
|
|
21
27
|
return types;
|
|
22
28
|
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useContext = void 0;
|
|
7
|
+
var _useConstant = require("../useConstant");
|
|
8
|
+
var _ahooks = require("ahooks");
|
|
9
|
+
var _ArgumentTypes = require("../../enums/ArgumentTypes");
|
|
10
|
+
var _useContextUseCase2 = require("../useContextUseCase");
|
|
11
|
+
var useContext = exports.useContext = function useContext(usecase) {
|
|
12
|
+
var argumentTypes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _ArgumentTypes.ArgumentTypes.None;
|
|
13
|
+
var _useContextUseCase = (0, _useContextUseCase2.useContextUseCase)(),
|
|
14
|
+
registerUseCase = _useContextUseCase.registerUseCase,
|
|
15
|
+
unregisterUseCase = _useContextUseCase.unregisterUseCase;
|
|
16
|
+
var context = (0, _useConstant.useConstant)(function () {
|
|
17
|
+
return registerUseCase(usecase, argumentTypes);
|
|
18
|
+
});
|
|
19
|
+
(0, _ahooks.useUnmount)(function () {
|
|
20
|
+
unregisterUseCase(usecase, argumentTypes);
|
|
21
|
+
});
|
|
22
|
+
return context;
|
|
23
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
|
|
5
|
+
var _globals = require("@jest/globals");
|
|
6
|
+
var _react = require("@testing-library/react");
|
|
7
|
+
var _ = require(".");
|
|
8
|
+
var _ArgumentTypes = require("../../enums/ArgumentTypes");
|
|
9
|
+
var _react2 = require("react");
|
|
10
|
+
var testUseCase = function testUseCase() {
|
|
11
|
+
return {};
|
|
12
|
+
};
|
|
13
|
+
(0, _globals.describe)('useContext', function () {
|
|
14
|
+
(0, _globals.test)('should return the default context with value `null` if map has not saved a usecase with default args', function () {
|
|
15
|
+
var _renderHook = (0, _react.renderHook)(function () {
|
|
16
|
+
var context = (0, _.useContext)(testUseCase);
|
|
17
|
+
var value = (0, _react2.useContext)(context);
|
|
18
|
+
return value;
|
|
19
|
+
}),
|
|
20
|
+
result = _renderHook.result;
|
|
21
|
+
var current = result.current;
|
|
22
|
+
(0, _globals.expect)(current).toBe(null);
|
|
23
|
+
});
|
|
24
|
+
(0, _globals.test)('should return the default context with value `null` if map has not saved a usecase with `ArgumentTypes.None` & `UseCaseModes.Normal`', function () {
|
|
25
|
+
var _renderHook2 = (0, _react.renderHook)(function () {
|
|
26
|
+
var context = (0, _.useContext)(testUseCase, _ArgumentTypes.ArgumentTypes.None);
|
|
27
|
+
var value = (0, _react2.useContext)(context);
|
|
28
|
+
return value;
|
|
29
|
+
}),
|
|
30
|
+
result = _renderHook2.result;
|
|
31
|
+
var current = result.current;
|
|
32
|
+
(0, _globals.expect)(current).toBe(null);
|
|
33
|
+
});
|
|
34
|
+
(0, _globals.test)('should return the default context with value `null` as unmount this hook', function () {
|
|
35
|
+
var _renderHook3 = (0, _react.renderHook)(function () {
|
|
36
|
+
var context = (0, _.useContext)(testUseCase, _ArgumentTypes.ArgumentTypes.None);
|
|
37
|
+
var value = (0, _react2.useContext)(context);
|
|
38
|
+
return value;
|
|
39
|
+
}),
|
|
40
|
+
result1 = _renderHook3.result,
|
|
41
|
+
unmount1 = _renderHook3.unmount;
|
|
42
|
+
var current1 = result1.current;
|
|
43
|
+
(0, _globals.expect)((0, _typeof2["default"])(current1)).toBe('object');
|
|
44
|
+
unmount1();
|
|
45
|
+
var _renderHook4 = (0, _react.renderHook)(function () {
|
|
46
|
+
var context = (0, _.useContext)(testUseCase, _ArgumentTypes.ArgumentTypes.None);
|
|
47
|
+
var value = (0, _react2.useContext)(context);
|
|
48
|
+
return value;
|
|
49
|
+
}),
|
|
50
|
+
result2 = _renderHook4.result;
|
|
51
|
+
var current2 = result2.current;
|
|
52
|
+
(0, _globals.expect)(current2).toBe(null);
|
|
53
|
+
});
|
|
54
|
+
(0, _globals.test)('should return a new context if map has not saved a usecase with `ArgumentTypes.Entity` & `UseCaseModes.Normal`', function () {
|
|
55
|
+
var _renderHook5 = (0, _react.renderHook)(function () {
|
|
56
|
+
return (0, _.useContext)(testUseCase, _ArgumentTypes.ArgumentTypes.Entity);
|
|
57
|
+
}),
|
|
58
|
+
result = _renderHook5.result;
|
|
59
|
+
var current = result.current;
|
|
60
|
+
(0, _globals.expect)((0, _typeof2["default"])(current)).toBe('object');
|
|
61
|
+
});
|
|
62
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useContextUseCase = void 0;
|
|
7
|
+
var _useConstant = require("../useConstant");
|
|
8
|
+
var _contextUseCase = require("../../usecases/contextUseCase");
|
|
9
|
+
var useContextUseCase = exports.useContextUseCase = function useContextUseCase() {
|
|
10
|
+
return (0, _useConstant.useConstant)(function () {
|
|
11
|
+
return (0, _contextUseCase.contextUseCase)();
|
|
12
|
+
});
|
|
13
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useContextValue = void 0;
|
|
7
|
+
var _useContextUseCase2 = require("../useContextUseCase");
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
var _ArgumentTypes = require("../../enums/ArgumentTypes");
|
|
10
|
+
var useContextValue = exports.useContextValue = function useContextValue(context, argumentType) {
|
|
11
|
+
var _useContextUseCase = (0, _useContextUseCase2.useContextUseCase)(),
|
|
12
|
+
getGlobalContextValue = _useContextUseCase.getGlobalContextValue;
|
|
13
|
+
var contextValue = (0, _react.useContext)(context);
|
|
14
|
+
var globalContextValue = getGlobalContextValue(context);
|
|
15
|
+
var isGlobal = (argumentType & _ArgumentTypes.ArgumentTypes.Global) === _ArgumentTypes.ArgumentTypes.Global;
|
|
16
|
+
if (isGlobal) {
|
|
17
|
+
return globalContextValue;
|
|
18
|
+
}
|
|
19
|
+
return contextValue;
|
|
20
|
+
};
|
|
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.useContextualItem = void 0;
|
|
7
7
|
var _ahooks = require("ahooks");
|
|
8
|
-
var
|
|
8
|
+
var _Statuses = require("../../enums/Statuses");
|
|
9
9
|
var _cacheCall = require("../../methods/cacheCall");
|
|
10
10
|
var useContextualItem = exports.useContextualItem = function useContextualItem(contextItem, statuses, createFactory) {
|
|
11
11
|
var depsKey = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
|
|
@@ -19,7 +19,7 @@ var useContextualItem = exports.useContextualItem = function useContextualItem(c
|
|
|
19
19
|
});
|
|
20
20
|
}, [depsKey, factoryRef]);
|
|
21
21
|
return (0, _ahooks.useCreation)(function () {
|
|
22
|
-
var rootEnabled = (statuses &
|
|
22
|
+
var rootEnabled = (statuses & _Statuses.Statuses.RootEnabled) === _Statuses.Statuses.RootEnabled;
|
|
23
23
|
if (!rootEnabled && contextItem) {
|
|
24
24
|
return contextItem;
|
|
25
25
|
}
|