@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.
Files changed (91) hide show
  1. package/dist/index.min.js +1 -1
  2. package/es/components/UseCaseFragment/index.d.ts +2 -2
  3. package/es/components/UseCaseFragment/types.d.ts +3 -3
  4. package/es/enums/ArgumentTypes/index.d.ts +6 -0
  5. package/es/enums/ArgumentTypes/index.js +7 -0
  6. package/es/enums/Statuses/index.d.ts +27 -0
  7. package/es/enums/Statuses/index.js +28 -0
  8. package/es/hooks/useArgumentTypes/index.d.ts +2 -2
  9. package/es/hooks/useArgumentTypes/index.js +9 -4
  10. package/es/hooks/useContext/index.d.ts +5 -0
  11. package/es/hooks/useContext/index.js +14 -0
  12. package/es/hooks/useContext/index.test.js +52 -0
  13. package/es/hooks/useContextUseCase/index.d.ts +2 -0
  14. package/es/hooks/useContextUseCase/index.js +7 -0
  15. package/es/hooks/useContextValue/index.d.ts +4 -0
  16. package/es/hooks/useContextValue/index.js +13 -0
  17. package/es/hooks/useContextualItem/index.d.ts +2 -2
  18. package/es/hooks/useContextualItem/index.js +2 -2
  19. package/es/hooks/useEntity/index.d.ts +2 -2
  20. package/es/hooks/useEntity/index.js +20 -20
  21. package/es/hooks/useFullArguments/index.d.ts +5 -0
  22. package/es/hooks/useFullArguments/index.js +22 -0
  23. package/es/{methods/fillArguments → hooks/useFullArguments}/types.d.ts +3 -2
  24. package/es/hooks/useProvider/index.d.ts +5 -4
  25. package/es/hooks/useProvider/index.js +7 -14
  26. package/es/hooks/useRuntimeEntity/index.d.ts +2 -2
  27. package/es/hooks/useRuntimeEntity/index.js +9 -9
  28. package/es/hooks/useStatuses/index.d.ts +5 -0
  29. package/es/hooks/useStatuses/index.js +27 -0
  30. package/es/hooks/useUseCase/index.js +13 -13
  31. package/es/hooks/useUseCase/index.test.js +106 -1
  32. package/es/hooks/useUseCase/types.d.ts +9 -9
  33. package/es/index.d.ts +1 -0
  34. package/es/index.js +1 -0
  35. package/es/methods/initEntityReducers/index.d.ts +4 -3
  36. package/es/methods/registerGlobalUseCase/index.d.ts +1 -0
  37. package/es/methods/registerGlobalUseCase/index.js +2 -0
  38. package/es/usecases/contextUseCase/index.d.ts +2 -2
  39. package/es/usecases/contextUseCase/index.js +99 -18
  40. package/es/usecases/contextUseCase/types.d.ts +33 -2
  41. package/lib/enums/ArgumentTypes/index.js +13 -0
  42. package/lib/enums/Statuses/index.js +34 -0
  43. package/lib/hooks/useArgumentTypes/index.js +9 -3
  44. package/lib/hooks/useContext/index.js +23 -0
  45. package/lib/hooks/useContext/index.test.js +62 -0
  46. package/lib/hooks/useContextUseCase/index.js +13 -0
  47. package/lib/hooks/useContextValue/index.js +20 -0
  48. package/lib/hooks/useContextualItem/index.js +2 -2
  49. package/lib/hooks/useEntity/index.js +21 -21
  50. package/lib/hooks/useFullArguments/index.js +25 -0
  51. package/lib/hooks/useProvider/index.js +8 -15
  52. package/lib/hooks/useRuntimeEntity/index.js +9 -9
  53. package/lib/hooks/useStatuses/index.js +33 -0
  54. package/lib/hooks/useUseCase/index.js +13 -13
  55. package/lib/hooks/useUseCase/index.test.js +152 -7
  56. package/lib/index.js +8 -1
  57. package/lib/methods/registerGlobalUseCase/index.js +9 -0
  58. package/lib/usecases/contextUseCase/index.js +103 -20
  59. package/package.json +3 -3
  60. package/es/configs/defaultUseCaseContext/index.d.ts +0 -4
  61. package/es/configs/defaultUseCaseContext/index.js +0 -2
  62. package/es/configs/defaultUseCaseContext/types.d.ts +0 -19
  63. package/es/configs/useCaseContextReferenceMap/index.d.ts +0 -1
  64. package/es/configs/useCaseContextReferenceMap/index.js +0 -1
  65. package/es/configs/useCaseContextReferenceMap/types.d.ts +0 -8
  66. package/es/configs/useCaseContextReferenceMap/types.js +0 -1
  67. package/es/enums/UseCaseArgumentTypes/index.d.ts +0 -4
  68. package/es/enums/UseCaseArgumentTypes/index.js +0 -5
  69. package/es/enums/UseCaseStatuses/index.d.ts +0 -8
  70. package/es/enums/UseCaseStatuses/index.js +0 -14
  71. package/es/hooks/useUseCaseContext/index.d.ts +0 -4
  72. package/es/hooks/useUseCaseContext/index.js +0 -48
  73. package/es/hooks/useUseCaseContext/index.test.js +0 -59
  74. package/es/hooks/useUseCaseStatuses/index.d.ts +0 -5
  75. package/es/hooks/useUseCaseStatuses/index.js +0 -22
  76. package/es/methods/fillArguments/index.d.ts +0 -5
  77. package/es/methods/fillArguments/index.js +0 -14
  78. package/es/methods/fillArguments/types.js +0 -1
  79. package/lib/configs/defaultUseCaseContext/index.js +0 -8
  80. package/lib/configs/useCaseContextReferenceMap/index.js +0 -7
  81. package/lib/configs/useCaseContextReferenceMap/types.js +0 -5
  82. package/lib/enums/UseCaseArgumentTypes/index.js +0 -11
  83. package/lib/enums/UseCaseStatuses/index.js +0 -20
  84. package/lib/hooks/useUseCaseContext/index.js +0 -57
  85. package/lib/hooks/useUseCaseContext/index.test.js +0 -73
  86. package/lib/hooks/useUseCaseStatuses/index.js +0 -28
  87. package/lib/methods/fillArguments/index.js +0 -21
  88. package/lib/methods/fillArguments/types.js +0 -5
  89. /package/es/hooks/{useUseCaseContext → useContext}/index.test.d.ts +0 -0
  90. /package/es/{configs/defaultUseCaseContext → hooks/useFullArguments}/types.js +0 -0
  91. /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 { EntityReducers, EntityUseCase, Reducers, UseCase } from '@mic-rexjs/usecases';
1
+ import { UseCase } from '@mic-rexjs/usecases';
2
2
  import { UseCaseProvider } from '../useProvider/types';
3
- import { ContextualEntityReducers } from '../../configs/defaultUseCaseContext/types';
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 EntityReducers<T>> = [
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 EntityReducers<T>> = [
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 EntityReducers<T>> = RootCoreCollection<T, TEntityReducers> | ContextualCoreCollection<T, TEntityReducers>;
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 Reducers, TUseCaseOptions extends object = object>(usecase: UseCase<T & SymbolSetTarget<NonEntitySymbolSet>, TUseCaseOptions>, options?: TUseCaseOptions, deps?: unknown[]): T;
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: EntityUseCase<T, TEntityReducers> & UseCase<EntityReducers<T>>, options?: UseCaseHookContextualOptions<T>, deps?: unknown[]): ContextualCoreCollection<T, TEntityReducers>;
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 EntityReducers<T>, TUseCaseOptions extends object = object>(entity: T | EntityGetter<T>, usecase: EntityUseCase<T, TEntityReducers, TUseCaseOptions> & UseCase<EntityReducers<T>, TUseCaseOptions>, options?: UseCaseHookOptions<T, TUseCaseOptions>, deps?: unknown[]): RootCoreCollection<T, TEntityReducers>;
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,2 +1,3 @@
1
1
  export { UseCaseFragment } from './components/UseCaseFragment';
2
2
  export { useUseCase } from './hooks/useUseCase';
3
+ export { registerGlobalUseCase } from './methods/registerGlobalUseCase';
@@ -1,4 +1,5 @@
1
- import { EntityReducers, EntityStore, EntityUseCase } from '@mic-rexjs/usecases';
1
+ import { EntityStore } from '@mic-rexjs/usecases';
2
2
  import { UseCaseHookOptions } from '../../hooks/useUseCase/types';
3
- import { ContextualEntityReducers } from '../../configs/defaultUseCaseContext/types';
4
- export declare const initEntityReducers: <T, TEntityReducers extends EntityReducers<T>, TUseCaseOptions extends object = object>(usecase: EntityUseCase<T, TEntityReducers, TUseCaseOptions>, store: EntityStore<T>, options: UseCaseHookOptions<T, TUseCaseOptions>) => ContextualEntityReducers<T, TEntityReducers>;
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;
@@ -0,0 +1,2 @@
1
+ import { contextUseCase } from '../../usecases/contextUseCase';
2
+ export const { registerGlobalUseCase } = contextUseCase();
@@ -1,2 +1,2 @@
1
- import { ContextReducers } from './types';
2
- export declare const contextUseCase: () => ContextReducers;
1
+ import { ContextUseCase } from './types';
2
+ export declare const contextUseCase: ContextUseCase;
@@ -1,19 +1,100 @@
1
- export const contextUseCase = () => {
2
- const hasContext = (target) => {
3
- if (typeof target !== 'object') {
4
- return false;
5
- }
6
- if (!Array.isArray(target)) {
7
- return false;
8
- }
9
- const { length } = target;
10
- const reducers = target[1];
11
- if (length < 2) {
12
- return false;
13
- }
14
- return typeof reducers === 'object';
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
- return {
17
- hasContext,
18
- };
19
- };
100
+ });
@@ -1,4 +1,35 @@
1
- import { Reducers } from '@mic-rexjs/usecases';
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
- hasContext<T>(target: T): boolean;
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 _UseCaseArgumentTypes = require("../../enums/UseCaseArgumentTypes");
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 = _UseCaseArgumentTypes.UseCaseArgumentTypes.None;
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 |= _UseCaseArgumentTypes.UseCaseArgumentTypes.Entity;
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 _UseCaseStatuses = require("../../enums/UseCaseStatuses");
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 & _UseCaseStatuses.UseCaseStatuses.RootEnabled) === _UseCaseStatuses.UseCaseStatuses.RootEnabled;
22
+ var rootEnabled = (statuses & _Statuses.Statuses.RootEnabled) === _Statuses.Statuses.RootEnabled;
23
23
  if (!rootEnabled && contextItem) {
24
24
  return contextItem;
25
25
  }