@mic-rexjs/usecases-react 3.7.0 → 4.0.0-beta.3

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 (150) hide show
  1. package/dist/index.min.js +1 -1
  2. package/dist/index.min.js.LICENSE.txt +2 -0
  3. package/es/components/UseCaseFragment/index.js +2 -2
  4. package/es/enums/Statuses/index.d.ts +86 -10
  5. package/es/enums/Statuses/index.js +86 -10
  6. package/es/hooks/useAlternateStatuses/index.d.ts +2 -0
  7. package/es/hooks/useAlternateStatuses/index.js +16 -0
  8. package/es/hooks/useChanged/index.d.ts +2 -0
  9. package/es/hooks/useChanged/index.js +17 -0
  10. package/es/hooks/useChanged/types.d.ts +3 -0
  11. package/es/hooks/useContext/index.d.ts +3 -4
  12. package/es/hooks/useContext/index.js +17 -15
  13. package/es/hooks/useContext/index.test.js +13 -24
  14. package/es/hooks/useContextValue/index.d.ts +5 -0
  15. package/es/hooks/useContextValue/index.js +13 -0
  16. package/es/hooks/useDepsKey/index.js +11 -9
  17. package/es/hooks/useEntity/index.d.ts +3 -2
  18. package/es/hooks/useEntity/index.js +52 -53
  19. package/es/hooks/useEntityReturn/index.d.ts +5 -0
  20. package/es/hooks/useEntityReturn/index.js +15 -0
  21. package/es/hooks/useEntityReturn/types.d.ts +7 -0
  22. package/es/hooks/useEntityRootExec/index.d.ts +5 -0
  23. package/es/hooks/useEntityRootExec/index.js +7 -0
  24. package/es/hooks/useEntityRootExec/types.d.ts +7 -0
  25. package/es/hooks/useEntityRootExec/types.js +1 -0
  26. package/es/hooks/useEntityRootReturn/index.d.ts +5 -0
  27. package/es/hooks/useEntityRootReturn/index.js +14 -0
  28. package/es/hooks/useEntityRootReturn/types.d.ts +7 -0
  29. package/es/hooks/useEntityRootReturn/types.js +1 -0
  30. package/es/hooks/useExec/index.d.ts +2 -3
  31. package/es/hooks/useExec/index.js +3 -12
  32. package/es/hooks/useExec/types.d.ts +10 -2
  33. package/es/hooks/useFullArguments/index.d.ts +2 -3
  34. package/es/hooks/useFullArguments/index.js +4 -6
  35. package/es/hooks/useFullArguments/types.d.ts +2 -2
  36. package/es/hooks/useIfExec/index.d.ts +2 -0
  37. package/es/hooks/useIfExec/index.js +20 -0
  38. package/es/hooks/useIfExec/types.d.ts +6 -0
  39. package/es/hooks/useIfExec/types.js +1 -0
  40. package/es/hooks/useIfReturn/index.d.ts +2 -0
  41. package/es/hooks/useIfReturn/index.js +22 -0
  42. package/es/hooks/useIfReturn/types.d.ts +6 -0
  43. package/es/hooks/useIfReturn/types.js +1 -0
  44. package/es/hooks/useProvider/index.d.ts +3 -5
  45. package/es/hooks/useProvider/index.js +17 -23
  46. package/es/hooks/useProviders/index.js +4 -4
  47. package/es/hooks/useReducers/index.d.ts +5 -4
  48. package/es/hooks/useReducers/index.js +45 -27
  49. package/es/hooks/useReturn/index.d.ts +2 -0
  50. package/es/hooks/useReturn/index.js +33 -0
  51. package/es/hooks/useReturn/types.d.ts +11 -0
  52. package/es/hooks/useReturn/types.js +1 -0
  53. package/es/hooks/useRootInitializing/index.d.ts +2 -0
  54. package/es/hooks/useRootInitializing/index.js +14 -0
  55. package/es/hooks/useRootReturn/index.d.ts +5 -0
  56. package/es/hooks/useRootReturn/index.js +22 -0
  57. package/es/hooks/useRootReturn/types.d.ts +14 -0
  58. package/es/hooks/useRootReturn/types.js +1 -0
  59. package/es/hooks/useStatuses/index.d.ts +4 -4
  60. package/es/hooks/useStatuses/index.js +46 -21
  61. package/es/hooks/useStore/index.d.ts +3 -3
  62. package/es/hooks/useStore/index.js +21 -49
  63. package/es/hooks/useThrottleUpdate/index.d.ts +2 -0
  64. package/es/hooks/useThrottleUpdate/index.js +31 -0
  65. package/es/hooks/useThrottleUpdate/types.d.ts +3 -0
  66. package/es/hooks/useThrottleUpdate/types.js +1 -0
  67. package/es/hooks/useUseCase/index.js +21 -24
  68. package/es/hooks/useUseCase/index.test.js +330 -98
  69. package/es/hooks/useUseCase/types.d.ts +15 -5
  70. package/es/methods/cacheCall/index.d.ts +2 -0
  71. package/es/methods/cacheCall/index.js +38 -0
  72. package/es/methods/cacheCall/types.d.ts +12 -0
  73. package/es/methods/cacheCall/types.js +1 -0
  74. package/es/methods/cacheCalls/index.d.ts +2 -0
  75. package/es/methods/cacheCalls/index.js +12 -0
  76. package/es/types.d.ts +2 -1
  77. package/es/usecases/contextUseCase/index.js +21 -38
  78. package/es/usecases/contextUseCase/types.d.ts +5 -6
  79. package/es/usecases/lifecycleEventUseCase/index.js +37 -9
  80. package/es/usecases/lifecycleEventUseCase/types.d.ts +11 -8
  81. package/lib/components/UseCaseFragment/index.js +2 -2
  82. package/lib/enums/Statuses/index.js +86 -10
  83. package/lib/hooks/useAlternateStatuses/index.js +22 -0
  84. package/lib/hooks/useChanged/index.js +23 -0
  85. package/lib/hooks/useContext/index.js +19 -17
  86. package/lib/hooks/useContext/index.test.js +13 -24
  87. package/lib/hooks/useContextValue/index.js +19 -0
  88. package/lib/hooks/useDepsKey/index.js +10 -8
  89. package/lib/hooks/useEntity/index.js +81 -54
  90. package/lib/hooks/useEntityReturn/index.js +22 -0
  91. package/lib/hooks/useEntityRootExec/index.js +13 -0
  92. package/lib/hooks/useEntityRootExec/types.js +5 -0
  93. package/lib/hooks/useEntityRootReturn/index.js +21 -0
  94. package/lib/hooks/useEntityRootReturn/types.js +5 -0
  95. package/lib/hooks/useExec/index.js +3 -12
  96. package/lib/hooks/useFullArguments/index.js +4 -6
  97. package/lib/hooks/useIfExec/index.js +27 -0
  98. package/lib/hooks/useIfExec/types.js +5 -0
  99. package/lib/hooks/useIfReturn/index.js +29 -0
  100. package/lib/hooks/useIfReturn/types.js +5 -0
  101. package/lib/hooks/useProvider/index.js +16 -22
  102. package/lib/hooks/useProviders/index.js +3 -3
  103. package/lib/hooks/useReducers/index.js +46 -29
  104. package/lib/hooks/useReturn/index.js +40 -0
  105. package/lib/hooks/useReturn/types.js +5 -0
  106. package/lib/hooks/useRootInitializing/index.js +20 -0
  107. package/lib/hooks/useRootReturn/index.js +30 -0
  108. package/lib/hooks/useRootReturn/types.js +5 -0
  109. package/lib/hooks/useStatuses/index.js +47 -21
  110. package/lib/hooks/useStore/index.js +19 -48
  111. package/lib/hooks/useThrottleUpdate/index.js +37 -0
  112. package/lib/hooks/useThrottleUpdate/types.js +5 -0
  113. package/lib/hooks/useUseCase/index.js +22 -25
  114. package/lib/hooks/useUseCase/index.test.js +360 -97
  115. package/lib/methods/cacheCall/index.js +44 -0
  116. package/lib/methods/cacheCall/types.js +5 -0
  117. package/lib/methods/cacheCalls/index.js +19 -0
  118. package/lib/usecases/contextUseCase/index.js +21 -38
  119. package/lib/usecases/lifecycleEventUseCase/index.js +48 -8
  120. package/package.json +3 -3
  121. package/es/enums/ArgumentTypes/index.d.ts +0 -4
  122. package/es/enums/ArgumentTypes/index.js +0 -5
  123. package/es/hooks/useArgumentTypes/index.d.ts +0 -3
  124. package/es/hooks/useArgumentTypes/index.js +0 -14
  125. package/es/hooks/useConstantEntityReducers/index.d.ts +0 -3
  126. package/es/hooks/useConstantEntityReducers/index.js +0 -7
  127. package/es/hooks/useConstantFn/index.d.ts +0 -1
  128. package/es/hooks/useConstantFn/index.js +0 -10
  129. package/es/hooks/useConstantReducers/index.d.ts +0 -3
  130. package/es/hooks/useConstantReducers/index.js +0 -6
  131. package/es/hooks/useContextualItem/index.d.ts +0 -4
  132. package/es/hooks/useContextualItem/index.js +0 -31
  133. package/es/hooks/useContextualItem/types.d.ts +0 -3
  134. package/es/hooks/useEntityInitializing/index.d.ts +0 -2
  135. package/es/hooks/useEntityInitializing/index.js +0 -16
  136. package/es/usecases/methodUseCase/index.d.ts +0 -2
  137. package/es/usecases/methodUseCase/index.js +0 -72
  138. package/es/usecases/methodUseCase/types.d.ts +0 -21
  139. package/lib/enums/ArgumentTypes/index.js +0 -11
  140. package/lib/hooks/useArgumentTypes/index.js +0 -22
  141. package/lib/hooks/useConstantEntityReducers/index.js +0 -13
  142. package/lib/hooks/useConstantFn/index.js +0 -17
  143. package/lib/hooks/useConstantReducers/index.js +0 -12
  144. package/lib/hooks/useContextualItem/index.js +0 -37
  145. package/lib/hooks/useEntityInitializing/index.js +0 -22
  146. package/lib/usecases/methodUseCase/index.js +0 -79
  147. /package/es/hooks/{useContextualItem → useChanged}/types.js +0 -0
  148. /package/es/{usecases/methodUseCase → hooks/useEntityReturn}/types.js +0 -0
  149. /package/lib/hooks/{useContextualItem → useChanged}/types.js +0 -0
  150. /package/lib/{usecases/methodUseCase → hooks/useEntityReturn}/types.js +0 -0
@@ -20,8 +20,6 @@ export type RootCoreCollection<T, TEntityReducers extends EntityReducerMap<T>> =
20
20
  * @deprecated 请用 `CoreCollection` 代替
21
21
  */
22
22
  export type ContextualCoreCollection<T, TEntityReducers extends EntityReducerMap<T>> = CoreCollection<T, TEntityReducers>;
23
- export interface EntityGetter<T> extends EntityInitializer<T> {
24
- }
25
23
  export interface EntityWatchEvent<T, TValue = unknown> extends MatchPropertyFailedResult<T, TValue> {
26
24
  }
27
25
  export interface EntityWatcher<T, TValue = unknown> {
@@ -37,11 +35,23 @@ export type ExtractFieldType<T, TPath> = TPath extends `${infer TKey}.${infer TS
37
35
  export type EntityWatchMap<T> = {
38
36
  [K in FieldPath<T>]?: EntityWatcher<T, ExtractFieldType<T, K>>;
39
37
  };
40
- export interface UseCaseHookContextualOptions<T> {
38
+ export interface ContextualUseCaseHookOptions<T> {
39
+ /**
40
+ * 触发机制包括以下两点:
41
+ *
42
+ * 1. 由相关 `reducers` 的调用行为触发 - 非渲染阶段;
43
+ * 2. 由 `useUseCase(entity, usecase)` 中的 `entity` 变化触发 - 渲染阶段。
44
+ */
41
45
  watch?: EntityWatchMap<T>;
46
+ /**
47
+ * 非渲染阶段触发,随后会触发组件的更新:
48
+ *
49
+ * 只由相关 `reducers` 的调用行为触发;
50
+ * 不包括 `useUseCase(entity, usecase)` 中的 `entity` 变化触发。
51
+ */
42
52
  onChange?(newEntity: T, oldEntity: T): void;
43
53
  }
44
- export interface UseCaseHookOwnOptions<T, TUseCaseOptions extends object> extends UseCaseHookContextualOptions<T> {
54
+ export interface UseCaseHookOwnOptions<T, TUseCaseOptions extends object> extends ContextualUseCaseHookOptions<T> {
45
55
  options?: TUseCaseOptions;
46
56
  }
47
57
  export type UnextendFunctionTypes<T> = T extends (...args: infer TArgs) => infer TReturn ? (...args: TArgs) => TReturn : T;
@@ -53,7 +63,7 @@ export interface ReducersHook {
53
63
  <T extends ReducerMap, TUseCaseOptions extends object = object>(usecase: UseCase<T & SymbolSetTarget<NonEntitySymbolSet>, TUseCaseOptions>, options?: TUseCaseOptions, deps?: Dependencies): T;
54
64
  }
55
65
  export interface ContextualCoreCollectionHook {
56
- <T, TEntityReducers extends EntityReducerMap<T>>(usecase: InferableEntityUseCase<T, TEntityReducers>, options?: UseCaseHookContextualOptions<T>, deps?: Dependencies): CoreCollection<T, TEntityReducers>;
66
+ <T, TEntityReducers extends EntityReducerMap<T>, TUseCaseOptions extends object = object>(usecase: InferableEntityUseCase<T, TEntityReducers, TUseCaseOptions>, options?: ContextualUseCaseHookOptions<T>): CoreCollection<T, TEntityReducers>;
57
67
  }
58
68
  export interface RootCoreCollectionHook {
59
69
  <T, TEntityReducers extends EntityReducerMap<T>, TUseCaseOptions extends object = object>(entity: T | EntityInitializer<T>, usecase: InferableEntityUseCase<T, TEntityReducers & EntityReducers<T>, TUseCaseOptions>, options?: UseCaseHookOptions<T, TUseCaseOptions>, deps?: Dependencies): CoreCollection<T, EntityReducers<T, TEntityReducers>>;
@@ -0,0 +1,2 @@
1
+ import { CacheableFactory, CacheCallOptions } from './types';
2
+ export declare const cacheCall: <T extends CacheableFactory>(factory: T, options?: CacheCallOptions) => T;
@@ -0,0 +1,38 @@
1
+ import { objectUtilsUseCase } from '../../usecases/objectUtilsUseCase';
2
+ export const cacheCall = (factory, options) => {
3
+ let cache;
4
+ const _objectUtilsUseCase = objectUtilsUseCase(),
5
+ isEqual = _objectUtilsUseCase.isEqual;
6
+ const _ref = options || {},
7
+ _ref$onShouldCache = _ref.onShouldCache,
8
+ onShouldCache = _ref$onShouldCache === void 0 ? () => {
9
+ return true;
10
+ } : _ref$onShouldCache,
11
+ _ref$onCompare = _ref.onCompare,
12
+ onCompare = _ref$onCompare === void 0 ? (newArgs, oldArgs) => {
13
+ return isEqual(newArgs, oldArgs);
14
+ } : _ref$onCompare;
15
+ return new Proxy(factory, {
16
+ apply(target, thisArg) {
17
+ let argList = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
18
+ const args = argList;
19
+ const cacheable = onShouldCache();
20
+ if (cache && cacheable) {
21
+ const _cache = cache,
22
+ parameters = _cache.parameters,
23
+ returnValue = _cache.returnValue;
24
+ if (onCompare(parameters, args)) {
25
+ return returnValue;
26
+ }
27
+ }
28
+ const returnValue = Reflect.apply(target, thisArg, args);
29
+ if (cacheable) {
30
+ cache = {
31
+ parameters: args,
32
+ returnValue
33
+ };
34
+ }
35
+ return returnValue;
36
+ }
37
+ });
38
+ };
@@ -0,0 +1,12 @@
1
+ import { RestArguments } from '@mic-rexjs/usecases/es/types';
2
+ export interface CacheableFactory {
3
+ (...args: RestArguments): unknown;
4
+ }
5
+ export interface CacheCallOptions {
6
+ onShouldCache?(): boolean;
7
+ onCompare?(newArgs: RestArguments, oldArgs: RestArguments): boolean;
8
+ }
9
+ export interface CallCache<T extends CacheableFactory> {
10
+ parameters: Parameters<T>;
11
+ returnValue: ReturnType<T>;
12
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ import { CacheableFactory, CacheCallOptions } from '../cacheCall/types';
2
+ export declare const cacheCalls: <T extends Record<string, CacheableFactory>>(sourceFactories: T, options?: CacheCallOptions) => T;
@@ -0,0 +1,12 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ import { cacheCall } from '../cacheCall';
3
+ export const cacheCalls = (sourceFactories, options) => {
4
+ const cachedFactories = {};
5
+ Object.entries(sourceFactories).forEach(_ref => {
6
+ let _ref2 = _slicedToArray(_ref, 2),
7
+ key = _ref2[0],
8
+ factory = _ref2[1];
9
+ cachedFactories[key] = cacheCall(factory, options);
10
+ });
11
+ return cachedFactories;
12
+ };
package/es/types.d.ts CHANGED
@@ -1,6 +1,7 @@
1
- import { AsyncEntityCallbackGenerator, EntityGenerator, RestArguments } from '@mic-rexjs/usecases/es/types';
1
+ import { AsyncEntityCallbackGenerator, EntityGenerator, EntityReducerMap, ReducerMap, RestArguments } from '@mic-rexjs/usecases/es/types';
2
2
  export interface Dependencies extends RestArguments {
3
3
  }
4
+ export type UnknownReducerMap<T> = ReducerMap | EntityReducerMap<T>;
4
5
  export type InitEntityResult<T> = T | EntityGenerator<T> | AsyncEntityCallbackGenerator<T>;
5
6
  export interface EntityInitializer<T> {
6
7
  (entity: T | undefined): InitEntityResult<T>;
@@ -1,67 +1,51 @@
1
1
  import { createUseCase } from '@mic-rexjs/usecases';
2
2
  import { createContext } from 'react';
3
- import { ArgumentTypes } from '../../enums/ArgumentTypes';
4
- import { Statuses } from '../../enums/Statuses';
5
3
  export const contextUseCase = createUseCase(() => {
6
4
  const referenceMap = new Map();
7
- const defaultUseCaseContext = createContext(null);
8
5
  return () => {
9
- const createContextValue = (store, reducers, statuses) => {
10
- if ((statuses & Statuses.EntityEnabled) === Statuses.EntityEnabled) {
11
- return {
12
- store,
13
- reducers,
14
- statuses
15
- };
16
- }
17
- return {
18
- reducers,
19
- statuses
20
- };
6
+ const getTypedReferenceMap = () => {
7
+ return referenceMap;
21
8
  };
22
- const getUseCaseContext = usecase => {
23
- if (!referenceMap.has(usecase)) {
24
- return defaultUseCaseContext;
9
+ const getContext = usecase => {
10
+ const map = getTypedReferenceMap();
11
+ if (!map.has(usecase)) {
12
+ return createContext(null);
25
13
  }
26
- const _referenceMap$get = referenceMap.get(usecase),
27
- value = _referenceMap$get.value;
14
+ const _map$get = map.get(usecase),
15
+ value = _map$get.value;
28
16
  return value;
29
17
  };
30
- const registerUseCase = (usecase, argumentTypes) => {
31
- if (referenceMap.has(usecase)) {
32
- const reference = referenceMap.get(usecase);
18
+ const registerUseCase = usecase => {
19
+ const map = getTypedReferenceMap();
20
+ if (map.has(usecase)) {
21
+ const reference = map.get(usecase);
33
22
  const value = reference.value,
34
23
  times = reference.times;
35
- referenceMap.set(usecase, {
24
+ map.set(usecase, {
36
25
  value,
37
26
  times: times + 1
38
27
  });
39
28
  return value;
40
29
  }
41
- if ((argumentTypes & ArgumentTypes.Entity) !== ArgumentTypes.Entity) {
42
- return defaultUseCaseContext;
43
- }
44
30
  const context = createContext(null);
45
- referenceMap.set(usecase, {
31
+ map.set(usecase, {
46
32
  value: context,
47
33
  times: 1
48
34
  });
49
35
  return context;
50
36
  };
51
- const unregisterUseCase = (usecase, argumentTypes) => {
52
- if ((argumentTypes & ArgumentTypes.Entity) !== ArgumentTypes.Entity) {
53
- return false;
54
- }
55
- if (!referenceMap.has(usecase)) {
37
+ const unregisterUseCase = usecase => {
38
+ const map = getTypedReferenceMap();
39
+ if (!map.has(usecase)) {
56
40
  return false;
57
41
  }
58
- const reference = referenceMap.get(usecase);
42
+ const reference = map.get(usecase);
59
43
  const value = reference.value,
60
44
  times = reference.times;
61
45
  if (times === 1) {
62
- referenceMap.delete(usecase);
46
+ map.delete(usecase);
63
47
  } else {
64
- referenceMap.set(usecase, {
48
+ map.set(usecase, {
65
49
  value,
66
50
  times: times - 1
67
51
  });
@@ -69,8 +53,7 @@ export const contextUseCase = createUseCase(() => {
69
53
  return true;
70
54
  };
71
55
  return {
72
- createContextValue,
73
- getUseCaseContext,
56
+ getContext,
74
57
  registerUseCase,
75
58
  unregisterUseCase
76
59
  };
@@ -1,8 +1,8 @@
1
1
  import { AsyncEntityGenerator, EntityGenerator, EntityReducer, EntityStore, ReducerKeys, Reducers } from '@mic-rexjs/usecases';
2
- import { EntityReducerMap, InferableUseCase, ReducerMap } from '@mic-rexjs/usecases/es/types';
3
- import { ArgumentTypes } from '../../enums/ArgumentTypes';
2
+ import { EntityReducerMap, EntityUseCase, ReducerMap } from '@mic-rexjs/usecases/es/types';
4
3
  import { Statuses } from '../../enums/Statuses';
5
4
  export interface UseCaseContextValue<T extends ReducerMap> {
5
+ key: React.Key;
6
6
  reducers: T;
7
7
  statuses: Statuses;
8
8
  }
@@ -20,10 +20,9 @@ export type ContextualEntityReducers<T, TEntityReducers extends EntityReducerMap
20
20
  [K in ReducerKeys<TEntityReducers>]: ContextualEntityReducer<T, TEntityReducers[K]>;
21
21
  };
22
22
  export type ContextReducers = Reducers<{
23
- createContextValue<T, TReducers extends ReducerMap>(store: EntityStore<T>, reducers: TReducers, statuses: Statuses): UseCaseContextValue<TReducers>;
24
- getUseCaseContext<T extends ReducerMap, TUseCaseOptions extends object>(usecase: InferableUseCase<T, TUseCaseOptions>): UseCaseContext<UseCaseContextValue<T>>;
25
- registerUseCase<T extends ReducerMap, TUseCaseOptions extends object>(usecase: InferableUseCase<T, TUseCaseOptions>, argumentTypes: ArgumentTypes): UseCaseContext<UseCaseContextValue<T>>;
26
- unregisterUseCase<T extends ReducerMap, TUseCaseOptions extends object>(usecase: InferableUseCase<T, TUseCaseOptions>, argumentTypes: ArgumentTypes): boolean;
23
+ getContext<T, TEntityReducers extends EntityReducerMap<T>, TUseCaseOptions extends object>(usecase: EntityUseCase<T, TEntityReducers, TUseCaseOptions>): UseCaseContext<EntityUseCaseContextValue<T, TEntityReducers>>;
24
+ registerUseCase<T, TEntityReducers extends EntityReducerMap<T>, TUseCaseOptions extends object>(usecase: EntityUseCase<T, TEntityReducers, TUseCaseOptions>): UseCaseContext<EntityUseCaseContextValue<T, TEntityReducers>>;
25
+ unregisterUseCase<T, TEntityReducers extends EntityReducerMap<T>, TUseCaseOptions extends object>(usecase: EntityUseCase<T, TEntityReducers, TUseCaseOptions>): boolean;
27
26
  }>;
28
27
  export interface ContextUseCase {
29
28
  (): ContextReducers;
@@ -1,30 +1,58 @@
1
- import { createUseCase } from '@mic-rexjs/usecases';
1
+ import { createUseCase, utilsUseCase } from '@mic-rexjs/usecases';
2
2
  export const lifecycleEventUseCase = createUseCase(() => {
3
3
  const map = new Map();
4
- let events = null;
4
+ const eventsList = [];
5
+ const _utilsUseCase = utilsUseCase(),
6
+ createKey = _utilsUseCase.createKey;
5
7
  /**
6
8
  * 逻辑是:先存,再绑定 `key`,再通过 `key` 获取,最后清除
7
9
  */
8
10
  return () => {
11
+ const createLifecycleKey = () => {
12
+ return createKey();
13
+ };
9
14
  const deleteLifecycleEvents = key => {
10
15
  return map.delete(key);
11
16
  };
12
17
  const bindLifecycleEventsKey = key => {
13
- if (events === null) {
18
+ const length = eventsList.length;
19
+ if (length === 0) {
14
20
  return {};
15
21
  }
16
- const currentEvents = events;
17
- events = null;
18
- map.set(key, currentEvents);
19
- return currentEvents;
22
+ const list = eventsList.splice(0);
23
+ const onEvent = (propertyKey, args) => {
24
+ let returnValue = void 0;
25
+ for (const events of list) {
26
+ const event = events[propertyKey];
27
+ if (typeof event !== 'function') {
28
+ continue;
29
+ }
30
+ returnValue !== null && returnValue !== void 0 ? returnValue : returnValue = Reflect.apply(event, null, args);
31
+ }
32
+ return returnValue;
33
+ };
34
+ const types = ['onBind', 'onUnbind', 'onAdopt', 'onDiscard', 'onChange', 'onUpdate'];
35
+ const entries = types.map(type => {
36
+ const event = function () {
37
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
38
+ args[_key] = arguments[_key];
39
+ }
40
+ return onEvent(type, args);
41
+ };
42
+ return [type, event];
43
+ });
44
+ const events = Object.fromEntries(entries);
45
+ map.set(key, events);
46
+ return events;
20
47
  };
21
48
  const getLifecycleEvents = key => {
22
49
  return map.get(key) || {};
23
50
  };
24
- const setLifecycleEvents = e => {
25
- events = e;
51
+ const setLifecycleEvents = events => {
52
+ eventsList.push(events);
26
53
  };
27
54
  return {
55
+ createLifecycleKey,
28
56
  deleteLifecycleEvents,
29
57
  setLifecycleEvents,
30
58
  getLifecycleEvents,
@@ -17,13 +17,22 @@ export interface LifecycleEvents<T = unknown> {
17
17
  * 2. `onUpdate` 或 `onChange` 的时候。
18
18
  */
19
19
  onAdopt(newEntity: T, oldEntity?: T): void;
20
+ /**
21
+ * 当 `entity` 被废弃时候调用,包括以下两种情况:
22
+ *
23
+ * 1. `onUpdate` 或 `onChange` 的时候;
24
+ * 2. `onUnbind` 的时候。
25
+ */
26
+ onDiscard(entity: T): void;
20
27
  /**
21
28
  * 非渲染阶段触发,随后会触发组件的更新:
22
29
  *
23
30
  * 只由相关 `reducers` 的调用行为触发;
24
31
  * 不包括 `useUseCase(entity, usecase)` 中的 `entity` 变化触发。
32
+ *
33
+ * @returns 返回一个布尔值,决定是否跳过组件更新。
25
34
  */
26
- onChange(newEntity: T, oldEntity: T): void;
35
+ onChange(newEntity: T, oldEntity: T): void | number | boolean | Promise<boolean>;
27
36
  /**
28
37
  * 触发机制包括以下两点:
29
38
  *
@@ -31,18 +40,12 @@ export interface LifecycleEvents<T = unknown> {
31
40
  * 2. 由 `useUseCase(entity, usecase)` 中的 `entity` 变化触发 - 渲染阶段。
32
41
  */
33
42
  onUpdate(newEntity: T, oldEntity: T): void;
34
- /**
35
- * 当 `entity` 被废弃时候调用,包括以下两种情况:
36
- *
37
- * 1. `onUpdate` 或 `onChange` 的时候;
38
- * 2. `onUnbind` 的时候。
39
- */
40
- onDiscard(entity: T): void;
41
43
  }
42
44
  export interface CaptureLifecycleEventsCallback<T> {
43
45
  (): T;
44
46
  }
45
47
  export type LifecycleEventReducers = Reducers<{
48
+ createLifecycleKey(): React.Key;
46
49
  deleteLifecycleEvents(key: React.Key): boolean;
47
50
  bindLifecycleEventsKey<T>(key: React.Key): Partial<LifecycleEvents<T>>;
48
51
  setLifecycleEvents<T>(events: Partial<LifecycleEvents<T>>): void;
@@ -19,8 +19,8 @@ var UseCaseFragment = exports.UseCaseFragment = function UseCaseFragment(_ref) {
19
19
  var usecase = _ref.usecase,
20
20
  props = (0, _objectWithoutProperties2["default"])(_ref, _excluded);
21
21
  var _useUseCase = (0, _useUseCase2.useUseCase)(_contextUseCase.contextUseCase),
22
- getUseCaseContext = _useUseCase.getUseCaseContext;
23
- var context = getUseCaseContext(usecase);
22
+ getContext = _useUseCase.getContext;
23
+ var context = getContext(usecase);
24
24
  var contextValue = (0, _react.useContext)(context);
25
25
  return (0, _jsxRuntime.jsx)(_react.Fragment, {
26
26
  children: contextValue === null ? null : (0, _jsxRuntime.jsx)(_SafeUseCaseFragment.SafeUseCaseFragment, _objectSpread({
@@ -8,23 +8,99 @@ var Statuses;
8
8
  (function (Statuses) {
9
9
  Statuses[Statuses["None"] = 0] = "None";
10
10
  /**
11
- * 是否需要初始化根 `redurcers`
11
+ * 是否启用 `entity`
12
12
  */
13
- Statuses[Statuses["RootEnabled"] = 2] = "RootEnabled";
13
+ Statuses[Statuses["Entity"] = 4] = "Entity";
14
14
  /**
15
- * 是否为上下文模式
15
+ * 是否以 `ReducersHook` 或 `RootCoreCollectionHook` 的形式被调用
16
16
  */
17
- Statuses[Statuses["ContextEnabled"] = 4] = "ContextEnabled";
17
+ Statuses[Statuses["RootRuntime"] = 8] = "RootRuntime";
18
18
  /**
19
- * 是否有 `entity`
19
+ * 是否以 `RootCoreCollectionHook` 的形式被调用
20
20
  */
21
- Statuses[Statuses["EntityEnabled"] = 8] = "EntityEnabled";
21
+ Statuses[Statuses["EntityRootRuntime"] = 12] = "EntityRootRuntime";
22
22
  /**
23
- * 是否为需要提供 `Provider` 去挂载根 `context`
23
+ * 是否以 `ContextualCoreCollectionHook` 的形式被调用
24
24
  */
25
- Statuses[Statuses["ContextRootEnabled"] = 6] = "ContextRootEnabled";
25
+ Statuses[Statuses["EntityContextRuntime"] = 20] = "EntityContextRuntime";
26
26
  /**
27
- * 是否初始化与 `entity` 相关的 `reducers`
27
+ * 当传入的 `entity` 参数变更时,状态会轮流切换到 `X` 或 `Y` 其中的一个。
28
28
  */
29
- Statuses[Statuses["EntityRootEnabled"] = 14] = "EntityRootEnabled";
29
+ Statuses[Statuses["InitialEntityX"] = 32] = "InitialEntityX";
30
+ /**
31
+ * 当传入的 `entity` 参数变更时,状态会轮流切换到 `X` 或 `Y` 其中的一个。
32
+ */
33
+ Statuses[Statuses["InitialEntityY"] = 64] = "InitialEntityY";
34
+ /**
35
+ * 当传入的 `entity` 参数变更时,生成相关的 `key`,可作为 `hooks` 的依赖。
36
+ *
37
+ * 使用方式:
38
+ * * `const entityKey = statuses & Statuses.EntityKey;`
39
+ */
40
+ Statuses[Statuses["InitialEntityKey"] = 96] = "InitialEntityKey";
41
+ /**
42
+ * 当传入的 `usecase` 参数变更时,状态会轮流切换到 `X` 或 `Y` 其中的一个。
43
+ */
44
+ Statuses[Statuses["UseCaseX"] = 128] = "UseCaseX";
45
+ /**
46
+ * 当传入的 `usecase` 参数变更时,状态会轮流切换到 `X` 或 `Y` 其中的一个。
47
+ */
48
+ Statuses[Statuses["UseCaseY"] = 256] = "UseCaseY";
49
+ /**
50
+ * 当传入的 `usecase` 参数变更时,生成相关的 `key`,可作为 `hooks` 的依赖。
51
+ *
52
+ * 使用方式:
53
+ * * `const usecaseKey = statuses & Statuses.UseCaseKey;`
54
+ */
55
+ Statuses[Statuses["UseCaseKey"] = 384] = "UseCaseKey";
56
+ /**
57
+ * 当传入的 `deps` 变更时,状态会轮流切换到 `X` 或 `Y` 其中的一个。
58
+ */
59
+ Statuses[Statuses["DepsX"] = 512] = "DepsX";
60
+ /**
61
+ * 当传入的 `deps` 变更时,状态会轮流切换到 `X` 或 `Y` 其中的一个。
62
+ */
63
+ Statuses[Statuses["DepsY"] = 1024] = "DepsY";
64
+ /**
65
+ * 当传入的 `deps` 变更时,生成相关的 `key`,可作为 `hooks` 的依赖。
66
+ *
67
+ * 使用方式:
68
+ * * `const depsKey = statuses & Statuses.DepsKey;`
69
+ */
70
+ Statuses[Statuses["DepsKey"] = 1536] = "DepsKey";
71
+ /**
72
+ * 当传入的 `usecase` 或 `deps` 参数变更时,状态会轮流切换到 `X` 或 `Y` 其中的一个;
73
+ * 表示将有新的 `reducers` 将会生成。
74
+ */
75
+ Statuses[Statuses["ReducersX"] = 2048] = "ReducersX";
76
+ /**
77
+ * 当传入的 `usecase` 或 `deps` 参数变更时,状态会轮流切换到 `X` 或 `Y` 其中的一个;
78
+ * 表示将有新的 `reducers` 将会生成。
79
+ */
80
+ Statuses[Statuses["ReducersY"] = 4096] = "ReducersY";
81
+ /**
82
+ * 当传入的 `usecase` 或 `deps` 参数变更时,生成相关的 `key`,可作为 `hooks` 的依赖。
83
+ *
84
+ * 使用方式:
85
+ * * `const reducersKey = statuses & Statuses.ReducersKey;`
86
+ */
87
+ Statuses[Statuses["ReducersKey"] = 6144] = "ReducersKey";
88
+ /**
89
+ * 以下情况变更时,状态会轮流切换到 `X` 或 `Y` 其中的一个:
90
+ * * 传入的 `usecase` 发生变化;
91
+ * * 调用 `useUseCase` 的形式发生变化;
92
+ * * 新增或移除根节点的 `Provider`;
93
+ */
94
+ Statuses[Statuses["RootX"] = 8192] = "RootX";
95
+ /**
96
+ * 以下情况变更时,状态会轮流切换到 `X` 或 `Y` 其中的一个:
97
+ * * 传入的 `usecase` 发生变化;
98
+ * * 调用 `useUseCase` 的形式发生变化;
99
+ * * 新增或移除根节点的 `Provider`;
100
+ */
101
+ Statuses[Statuses["RootY"] = 16384] = "RootY";
102
+ /**
103
+ * 根据 `root` 的变化,生成相关的 `key`,可作为 `hooks` 的依赖。
104
+ */
105
+ Statuses[Statuses["RootKey"] = 24576] = "RootKey";
30
106
  })(Statuses || (exports.Statuses = Statuses = {}));
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useAlternateStatuses = void 0;
7
+ var _useChanged = require("../useChanged");
8
+ var _useReturn = require("../useReturn");
9
+ var _react = require("react");
10
+ var useAlternateStatuses = exports.useAlternateStatuses = function useAlternateStatuses(value, statusesX, statusesY) {
11
+ var statuesRef = (0, _react.useRef)(statusesX);
12
+ var isChanged = (0, _useChanged.useChanged)(value);
13
+ return (0, _useReturn.useReturn)(function () {
14
+ var currentStatuses = statuesRef.current;
15
+ if (!isChanged) {
16
+ return currentStatuses;
17
+ }
18
+ var newStatuses = currentStatuses === statusesX ? statusesY : statusesX;
19
+ statuesRef.current = newStatuses;
20
+ return newStatuses;
21
+ });
22
+ };
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useChanged = void 0;
7
+ var _ahooks = require("ahooks");
8
+ var useChanged = exports.useChanged = function useChanged(value) {
9
+ var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function (newValue, oldValue) {
10
+ return newValue !== oldValue;
11
+ };
12
+ var prevValue = (0, _ahooks.usePrevious)(value, function () {
13
+ /**
14
+ * 这里一定要返回 `true`,不然 `value` 没有改变的话,那么 `prevValue` 也不会变,
15
+ * 比如:首次 `value=1`,那么 `prevValue` 的值会一直是 `undefined`,
16
+ * 就算组件刷新了无数次,它也是 `undefined`。
17
+ *
18
+ * 而我们期望的是:当组件第二次刷新,`prevValue` 应该是 `1`。
19
+ */
20
+ return true;
21
+ });
22
+ return callback(value, prevValue);
23
+ };
@@ -4,21 +4,23 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.useContext = void 0;
7
- var _useConstant = require("../useConstant");
8
- var _ahooks = require("ahooks");
9
- var _ArgumentTypes = require("../../enums/ArgumentTypes");
10
- var _contextUseCase3 = require("../../usecases/contextUseCase");
11
- var useContext = exports.useContext = function useContext(usecase) {
12
- var argumentTypes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _ArgumentTypes.ArgumentTypes.None;
13
- var context = (0, _useConstant.useConstant)(function () {
14
- var _contextUseCase = (0, _contextUseCase3.contextUseCase)(),
15
- registerUseCase = _contextUseCase.registerUseCase;
16
- return registerUseCase(usecase, argumentTypes);
17
- });
18
- (0, _ahooks.useUnmount)(function () {
19
- var _contextUseCase2 = (0, _contextUseCase3.contextUseCase)(),
20
- unregisterUseCase = _contextUseCase2.unregisterUseCase;
21
- unregisterUseCase(usecase, argumentTypes);
22
- });
23
- return context;
7
+ var _useConstant2 = require("../useConstant");
8
+ var _useReturn = require("../useReturn");
9
+ var _contextUseCase = require("../../usecases/contextUseCase");
10
+ var useContext = exports.useContext = function useContext(usecase, isEntityRoot) {
11
+ var _useConstant = (0, _useConstant2.useConstant)(_contextUseCase.contextUseCase),
12
+ getContext = _useConstant.getContext,
13
+ registerUseCase = _useConstant.registerUseCase,
14
+ unregisterUseCase = _useConstant.unregisterUseCase;
15
+ return (0, _useReturn.useReturn)(function () {
16
+ if (isEntityRoot) {
17
+ return registerUseCase(usecase);
18
+ }
19
+ return getContext(usecase);
20
+ }, function () {
21
+ if (!isEntityRoot) {
22
+ return;
23
+ }
24
+ unregisterUseCase(usecase);
25
+ }, [usecase, isEntityRoot]);
24
26
  };
@@ -6,14 +6,13 @@ var _ = require(".");
6
6
  var _globals = require("@jest/globals");
7
7
  var _react = require("@testing-library/react");
8
8
  var _react2 = require("react");
9
- var _ArgumentTypes = require("../../enums/ArgumentTypes");
10
9
  var testUseCase = function testUseCase() {
11
10
  return {};
12
11
  };
13
12
  (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 () {
13
+ (0, _globals.test)('should return the default context with value `null` if map has not saved a usecase without entity root mode', function () {
15
14
  var _renderHook = (0, _react.renderHook)(function () {
16
- var context = (0, _.useContext)(testUseCase);
15
+ var context = (0, _.useContext)(testUseCase, false);
17
16
  var value = (0, _react2.useContext)(context);
18
17
  return value;
19
18
  }),
@@ -21,41 +20,31 @@ var testUseCase = function testUseCase() {
21
20
  var current = result.current;
22
21
  (0, _globals.expect)(current).toBe(null);
23
22
  });
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 () {
23
+ (0, _globals.test)('should return the default context with value `null` after unmount this hook', function () {
25
24
  var _renderHook2 = (0, _react.renderHook)(function () {
26
- var context = (0, _.useContext)(testUseCase, _ArgumentTypes.ArgumentTypes.None);
25
+ var context = (0, _.useContext)(testUseCase, false);
27
26
  var value = (0, _react2.useContext)(context);
28
27
  return value;
29
28
  }),
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;
29
+ result1 = _renderHook2.result,
30
+ unmount1 = _renderHook2.unmount;
42
31
  var current1 = result1.current;
43
32
  (0, _globals.expect)((0, _typeof2["default"])(current1)).toBe('object');
44
33
  unmount1();
45
- var _renderHook4 = (0, _react.renderHook)(function () {
46
- var context = (0, _.useContext)(testUseCase, _ArgumentTypes.ArgumentTypes.None);
34
+ var _renderHook3 = (0, _react.renderHook)(function () {
35
+ var context = (0, _.useContext)(testUseCase, false);
47
36
  var value = (0, _react2.useContext)(context);
48
37
  return value;
49
38
  }),
50
- result2 = _renderHook4.result;
39
+ result2 = _renderHook3.result;
51
40
  var current2 = result2.current;
52
41
  (0, _globals.expect)(current2).toBe(null);
53
42
  });
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);
43
+ (0, _globals.test)('should return a new context if map has not saved a usecase with entity root mode', function () {
44
+ var _renderHook4 = (0, _react.renderHook)(function () {
45
+ return (0, _.useContext)(testUseCase, true);
57
46
  }),
58
- result = _renderHook5.result;
47
+ result = _renderHook4.result;
59
48
  var current = result.current;
60
49
  (0, _globals.expect)((0, _typeof2["default"])(current)).toBe('object');
61
50
  });