@mic-rexjs/usecases-react 1.7.8 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.min.js +1 -1
- package/es/configs/defaultUseCaseContext/index.d.ts +2 -3
- package/es/configs/defaultUseCaseContext/index.js +1 -1
- package/es/configs/defaultUseCaseContext/types.d.ts +11 -3
- package/es/configs/usecaseContextMap/types.d.ts +2 -5
- package/es/enums/UseCaseModes/index.d.ts +6 -0
- package/es/enums/UseCaseModes/index.js +7 -0
- package/es/hooks/useChangeCallbackCollection/index.d.ts +3 -0
- package/es/hooks/useChangeCallbackCollection/index.js +29 -0
- package/es/hooks/useGlobalUseCase/index.d.ts +2 -0
- package/es/hooks/useGlobalUseCase/index.js +11 -0
- package/es/hooks/useGlobalUseCase/index.test.js +71 -0
- package/es/hooks/useGlobalUseCase/types.d.ts +12 -0
- package/es/hooks/useGlobalUseCase/types.js +1 -0
- package/es/hooks/useProvider/index.d.ts +3 -5
- package/es/hooks/useProvider/index.js +25 -15
- package/es/hooks/useProvider/types.d.ts +5 -1
- package/es/hooks/useStatelessUseCase/index.d.ts +2 -0
- package/es/hooks/useStatelessUseCase/index.js +8 -0
- package/es/hooks/useStatelessUseCase/index.test.d.ts +1 -0
- package/es/hooks/useStatelessUseCase/index.test.js +75 -0
- package/es/hooks/useStatelessUseCase/types.d.ts +5 -0
- package/es/hooks/useStatelessUseCase/types.js +1 -0
- package/es/hooks/useUseCase/index.js +27 -29
- package/es/hooks/useUseCase/index.test.js +273 -202
- package/es/hooks/useUseCase/types.d.ts +55 -8
- package/es/hooks/useUseCaseContext/index.d.ts +2 -2
- package/es/hooks/useUseCaseContext/index.js +1 -1
- package/es/index.d.ts +2 -0
- package/es/index.js +2 -0
- package/es/methods/getRootEntity/index.d.ts +2 -1
- package/es/methods/getRootEntity/index.js +6 -5
- package/es/methods/initEntityReducers/index.js +1 -1
- package/es/methods/toMaxArguments/index.d.ts +3 -0
- package/es/methods/toMaxArguments/index.js +28 -0
- package/es/methods/triggerCallbacks/index.d.ts +2 -3
- package/es/methods/triggerCallbacks/index.js +3 -12
- package/lib/configs/defaultUseCaseContext/index.js +1 -1
- package/lib/enums/UseCaseModes/index.js +14 -0
- package/lib/hooks/useChangeCallbackCollection/index.js +37 -0
- package/lib/hooks/useGlobalUseCase/index.js +25 -0
- package/lib/hooks/useGlobalUseCase/index.test.js +78 -0
- package/lib/hooks/useProvider/index.js +30 -20
- package/lib/hooks/useStatelessUseCase/index.js +22 -0
- package/lib/hooks/useStatelessUseCase/index.test.js +78 -0
- package/lib/hooks/useStatelessUseCase/types.js +5 -0
- package/lib/hooks/useUseCase/index.js +40 -31
- package/lib/hooks/useUseCase/index.test.js +380 -281
- package/lib/hooks/useUseCaseContext/index.js +1 -1
- package/lib/index.js +15 -1
- package/lib/methods/getRootEntity/index.js +6 -5
- package/lib/methods/initEntityReducers/index.js +2 -3
- package/lib/methods/toMaxArguments/index.js +25 -0
- package/lib/methods/triggerCallbacks/index.js +3 -13
- package/package.json +1 -1
- package/es/hooks/useOptionsRefCollection/index.d.ts +0 -3
- package/es/hooks/useOptionsRefCollection/index.js +0 -22
- package/es/hooks/useOptionsRefCollection/types.d.ts +0 -2
- package/lib/hooks/useOptionsRefCollection/index.js +0 -29
- /package/es/hooks/{useOptionsRefCollection/types.js → useGlobalUseCase/index.test.d.ts} +0 -0
- /package/lib/hooks/{useOptionsRefCollection → useGlobalUseCase}/types.js +0 -0
|
@@ -5,9 +5,11 @@ 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 { UseCaseModes } from '../../enums/UseCaseModes';
|
|
8
9
|
const EXT_1 = '.png';
|
|
9
10
|
const EXT_2 = '.jpg';
|
|
10
11
|
const PATH_1 = `hello${EXT_1}`;
|
|
12
|
+
const PATH_2 = `hello${EXT_2}`;
|
|
11
13
|
const PARENT_BUTTON_TEXT = 'parent button';
|
|
12
14
|
const CHILD_BUTTON_TEXT = 'child button';
|
|
13
15
|
const defaultFile = {
|
|
@@ -65,7 +67,7 @@ const Child = ({ textPrefix = '', onUpdate, onPathChange, onUndefinedEntity }) =
|
|
|
65
67
|
const [file, { setPath }] = useUseCase(fileUseCase);
|
|
66
68
|
const { path, ext } = file || {};
|
|
67
69
|
const onClick = () => {
|
|
68
|
-
setPath(
|
|
70
|
+
setPath(PATH_2);
|
|
69
71
|
};
|
|
70
72
|
const undefinedEntity = useMemoizedFn(() => {
|
|
71
73
|
onUndefinedEntity?.();
|
|
@@ -84,8 +86,8 @@ const Child = ({ textPrefix = '', onUpdate, onPathChange, onUndefinedEntity }) =
|
|
|
84
86
|
useUpdateEffect(pathChange, [path, pathChange]);
|
|
85
87
|
return (_jsxs("div", { children: [_jsxs("main", { children: ["child path: ", path, _jsx("br", {}), "child ext: ", ext] }), _jsx("footer", { children: _jsx("button", { onClick: onClick, children: textPrefix + CHILD_BUTTON_TEXT }) })] }));
|
|
86
88
|
};
|
|
87
|
-
const Parent = ({ children,
|
|
88
|
-
const [{ path, ext }, { setPath }, Provider] = useUseCase(defaultFile, fileUseCase,
|
|
89
|
+
const Parent = ({ children, mode, onUpdate, onSetPath }) => {
|
|
90
|
+
const [{ path, ext }, { setPath }, Provider] = useUseCase(defaultFile, fileUseCase, mode);
|
|
89
91
|
const onClick = () => {
|
|
90
92
|
setPath(onSetPath?.() || '');
|
|
91
93
|
};
|
|
@@ -122,17 +124,17 @@ beforeEach(() => {
|
|
|
122
124
|
subtractionReducer.mockClear();
|
|
123
125
|
});
|
|
124
126
|
describe('useUseCase', () => {
|
|
125
|
-
describe('`useUseCase` should work
|
|
127
|
+
describe.each([void 0, UseCaseModes.Normal, UseCaseModes.Global])('[mode=%s]: `useUseCase` should work the same as `useRootCoreCollection`', (mode) => {
|
|
126
128
|
test('check `context.length`', () => {
|
|
127
129
|
const { result } = renderHook(() => {
|
|
128
|
-
return useUseCase(defaultFile, fileUseCase);
|
|
130
|
+
return useUseCase(defaultFile, fileUseCase, mode);
|
|
129
131
|
});
|
|
130
132
|
const { current: cores } = result;
|
|
131
133
|
expect(cores).toHaveLength(3);
|
|
132
134
|
});
|
|
133
135
|
test('`entity` should equal `defaultFile`', () => {
|
|
134
136
|
const { result } = renderHook(() => {
|
|
135
|
-
return useUseCase(defaultFile, fileUseCase);
|
|
137
|
+
return useUseCase(defaultFile, fileUseCase, mode);
|
|
136
138
|
});
|
|
137
139
|
const { current: cores } = result;
|
|
138
140
|
const [entity] = cores;
|
|
@@ -410,13 +412,13 @@ describe('useUseCase', () => {
|
|
|
410
412
|
fireEvent.click(screen.getByText(updateButtonText));
|
|
411
413
|
expect(addReducer).toHaveBeenCalledTimes(3);
|
|
412
414
|
});
|
|
413
|
-
test('
|
|
415
|
+
test('stateless mode should not generate new reducers when `yeild entity`', () => {
|
|
414
416
|
const onUpdate = jest.fn();
|
|
415
417
|
const { result, rerender } = renderHook((file = defaultFile) => {
|
|
416
418
|
useUpdateEffect(() => {
|
|
417
419
|
onUpdate();
|
|
418
420
|
});
|
|
419
|
-
return useUseCase(file, fileUseCase,
|
|
421
|
+
return useUseCase(file, fileUseCase, UseCaseModes.Stateless);
|
|
420
422
|
});
|
|
421
423
|
const { current: cores } = result;
|
|
422
424
|
const [, { setPath }] = cores;
|
|
@@ -428,13 +430,13 @@ describe('useUseCase', () => {
|
|
|
428
430
|
expect(result.current[0].path).toBe(PATH_1);
|
|
429
431
|
expect(result.current[1].setPath).not.toBe(setPath);
|
|
430
432
|
});
|
|
431
|
-
test('
|
|
433
|
+
test('stateless mode should not trigger update when after `yield entity`', () => {
|
|
432
434
|
const onUpdate = jest.fn();
|
|
433
435
|
const { result } = renderHook(() => {
|
|
434
436
|
useUpdateEffect(() => {
|
|
435
437
|
onUpdate();
|
|
436
438
|
});
|
|
437
|
-
return useUseCase(defaultFile, fileUseCase,
|
|
439
|
+
return useUseCase(defaultFile, fileUseCase, UseCaseModes.Stateless);
|
|
438
440
|
});
|
|
439
441
|
const { current: cores } = result;
|
|
440
442
|
const [, reducers] = cores;
|
|
@@ -1110,216 +1112,96 @@ describe('useUseCase', () => {
|
|
|
1110
1112
|
oldValue: EXT_1,
|
|
1111
1113
|
});
|
|
1112
1114
|
});
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
const
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
const { current: reducers } = result;
|
|
1120
|
-
expect(Array.isArray(reducers)).toBe(false);
|
|
1121
|
-
});
|
|
1122
|
-
test('returned reducer should work', () => {
|
|
1123
|
-
const { result } = renderHook(() => {
|
|
1124
|
-
return useUseCase(mathUseCase);
|
|
1125
|
-
});
|
|
1126
|
-
const { current: reducers } = result;
|
|
1127
|
-
const { add } = reducers;
|
|
1128
|
-
expect(add(1, 2)).toBe(3);
|
|
1129
|
-
});
|
|
1130
|
-
test('`usecase` should be called only once if deps has not provided', () => {
|
|
1131
|
-
const mockUseCase = jest.fn(mathUseCase);
|
|
1132
|
-
const { rerender } = renderHook(() => {
|
|
1133
|
-
return useUseCase(mockUseCase);
|
|
1134
|
-
});
|
|
1135
|
-
expect(mockUseCase).toHaveBeenCalledTimes(1);
|
|
1136
|
-
rerender();
|
|
1137
|
-
expect(mockUseCase).toHaveBeenCalledTimes(1);
|
|
1138
|
-
});
|
|
1139
|
-
test('`usecase` should be called only once if deps has not changed', () => {
|
|
1140
|
-
const mockUseCase = jest.fn(mathUseCase);
|
|
1141
|
-
const { rerender } = renderHook(() => {
|
|
1142
|
-
return useUseCase(mockUseCase, {}, [1, 'x']);
|
|
1143
|
-
});
|
|
1144
|
-
expect(mockUseCase).toHaveBeenCalledTimes(1);
|
|
1145
|
-
rerender();
|
|
1146
|
-
expect(mockUseCase).toHaveBeenCalledTimes(1);
|
|
1147
|
-
});
|
|
1148
|
-
test('`usecase` should be called if deps has changed', () => {
|
|
1149
|
-
let i = 0;
|
|
1150
|
-
const mockUseCase = jest.fn(mathUseCase);
|
|
1151
|
-
const { rerender } = renderHook(() => {
|
|
1152
|
-
return useUseCase(mockUseCase, {}, [i++, 'x']);
|
|
1153
|
-
});
|
|
1154
|
-
expect(mockUseCase).toHaveBeenCalledTimes(1);
|
|
1155
|
-
rerender();
|
|
1156
|
-
expect(mockUseCase).toHaveBeenCalledTimes(2);
|
|
1157
|
-
});
|
|
1158
|
-
test('reducer call should not be cached if component is at rendering phase', () => {
|
|
1159
|
-
const buttonText = 'button';
|
|
1160
|
-
const CacheTestComponent = () => {
|
|
1161
|
-
const { subtraction } = useUseCase(mathUseCase);
|
|
1162
|
-
const update = useUpdate();
|
|
1163
|
-
const onClick = () => {
|
|
1164
|
-
update();
|
|
1165
|
-
};
|
|
1166
|
-
subtraction(5, 3);
|
|
1167
|
-
return _jsx("button", { onClick: onClick, children: buttonText });
|
|
1115
|
+
test('multiple `Provider` should work', () => {
|
|
1116
|
+
const onNumberMount = jest.fn();
|
|
1117
|
+
const onStringMount = jest.fn();
|
|
1118
|
+
const onBooleanMount = jest.fn();
|
|
1119
|
+
const numberUseCase = () => {
|
|
1120
|
+
return objectUseCase();
|
|
1168
1121
|
};
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
const buttonText = 'button';
|
|
1180
|
-
const CacheTestComponent = () => {
|
|
1181
|
-
const { subtraction } = useUseCase(mathUseCase);
|
|
1182
|
-
const onClick = () => {
|
|
1183
|
-
subtraction(5, 3);
|
|
1184
|
-
};
|
|
1122
|
+
const stringUseCase = () => {
|
|
1123
|
+
return objectUseCase();
|
|
1124
|
+
};
|
|
1125
|
+
const booleanUseCase = () => {
|
|
1126
|
+
return objectUseCase();
|
|
1127
|
+
};
|
|
1128
|
+
const TestChildComponent = () => {
|
|
1129
|
+
const [numberValue] = useUseCase(numberUseCase);
|
|
1130
|
+
const [stringValue] = useUseCase(stringUseCase);
|
|
1131
|
+
const [booleanValue] = useUseCase(booleanUseCase);
|
|
1185
1132
|
useMount(() => {
|
|
1186
|
-
|
|
1187
|
-
|
|
1133
|
+
onNumberMount(numberValue);
|
|
1134
|
+
onStringMount(stringValue);
|
|
1135
|
+
onBooleanMount(booleanValue);
|
|
1188
1136
|
});
|
|
1189
|
-
return
|
|
1137
|
+
return null;
|
|
1190
1138
|
};
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
expect(subtractionReducer).toHaveNthReturnedWith(2, 2);
|
|
1197
|
-
fireEvent.click(screen.getByText(buttonText));
|
|
1198
|
-
expect(subtractionReducer).toHaveBeenCalledTimes(3);
|
|
1199
|
-
expect(subtractionReducer).toHaveBeenNthCalledWith(3, 5, 3);
|
|
1200
|
-
expect(subtractionReducer).toHaveNthReturnedWith(3, 2);
|
|
1201
|
-
});
|
|
1202
|
-
test('reducer call should not be cached if parameters have changed', () => {
|
|
1203
|
-
let count = 0;
|
|
1204
|
-
const buttonText = 'button';
|
|
1205
|
-
const StringUseCaseTestComponent = () => {
|
|
1206
|
-
const { subtraction } = useUseCase(mathUseCase);
|
|
1207
|
-
const update = useUpdate();
|
|
1208
|
-
subtraction(5, count++);
|
|
1209
|
-
const onUpdate = () => {
|
|
1210
|
-
update();
|
|
1211
|
-
};
|
|
1212
|
-
return (_jsx("div", { children: _jsx("button", { onClick: onUpdate, children: buttonText }) }));
|
|
1139
|
+
const TestParentComponent = () => {
|
|
1140
|
+
const [, , NumberProvider] = useUseCase(11, numberUseCase);
|
|
1141
|
+
const [, , StringProvider] = useUseCase('hello', stringUseCase);
|
|
1142
|
+
const [, , BooleanProvider] = useUseCase(true, booleanUseCase);
|
|
1143
|
+
return (_jsx(NumberProvider, { with: [StringProvider, BooleanProvider], children: _jsx(TestChildComponent, {}) }));
|
|
1213
1144
|
};
|
|
1214
|
-
render(_jsx(
|
|
1215
|
-
expect(
|
|
1216
|
-
expect(
|
|
1217
|
-
|
|
1218
|
-
expect(subtractionReducer).toHaveBeenCalledTimes(2);
|
|
1219
|
-
expect(subtractionReducer).toHaveBeenCalledWith(5, 1);
|
|
1220
|
-
expect(subtractionReducer).toHaveReturnedWith(4);
|
|
1221
|
-
});
|
|
1222
|
-
test('`options.extraValue` should be added after call `add` method', () => {
|
|
1223
|
-
const { result } = renderHook(() => {
|
|
1224
|
-
return useUseCase(mathUseCase, { extraValue: 5 });
|
|
1225
|
-
});
|
|
1226
|
-
const { current: reducers } = result;
|
|
1227
|
-
const { add } = reducers;
|
|
1228
|
-
expect(add(1, 2)).toBe(8);
|
|
1229
|
-
});
|
|
1230
|
-
test('when `options` has changed, it should not trigger update', () => {
|
|
1231
|
-
const onUpdate = jest.fn();
|
|
1232
|
-
const onDeepUpdate = jest.fn();
|
|
1233
|
-
const { result } = renderHook(() => {
|
|
1234
|
-
const [extraValue, setExtraValue] = useState(0);
|
|
1235
|
-
const reducers = useUseCase(mathUseCase, { extraValue });
|
|
1236
|
-
useUpdateEffect(() => {
|
|
1237
|
-
onUpdate();
|
|
1238
|
-
}, [reducers]);
|
|
1239
|
-
useDeepCompareUpdate(() => {
|
|
1240
|
-
onDeepUpdate();
|
|
1241
|
-
}, [reducers]);
|
|
1242
|
-
return setExtraValue;
|
|
1243
|
-
});
|
|
1244
|
-
expect(onUpdate).toHaveBeenCalledTimes(0);
|
|
1245
|
-
expect(onDeepUpdate).toHaveBeenCalledTimes(0);
|
|
1246
|
-
act(() => {
|
|
1247
|
-
result.current(3);
|
|
1248
|
-
});
|
|
1249
|
-
expect(onUpdate).toHaveBeenCalledTimes(0);
|
|
1250
|
-
expect(onDeepUpdate).toHaveBeenCalledTimes(0);
|
|
1251
|
-
});
|
|
1252
|
-
test('when `deps` change, it should update reducers', () => {
|
|
1253
|
-
const onUpdate = jest.fn();
|
|
1254
|
-
const onDeepUpdate = jest.fn();
|
|
1255
|
-
const { result } = renderHook(() => {
|
|
1256
|
-
const [extraValue, setExtraValue] = useState(0);
|
|
1257
|
-
const reducers = useUseCase(mathUseCase, { extraValue }, [extraValue]);
|
|
1258
|
-
useUpdateEffect(() => {
|
|
1259
|
-
onUpdate();
|
|
1260
|
-
}, [reducers]);
|
|
1261
|
-
useDeepCompareUpdate(() => {
|
|
1262
|
-
onDeepUpdate();
|
|
1263
|
-
}, [reducers]);
|
|
1264
|
-
return setExtraValue;
|
|
1265
|
-
});
|
|
1266
|
-
expect(onUpdate).toHaveBeenCalledTimes(0);
|
|
1267
|
-
expect(onDeepUpdate).toHaveBeenCalledTimes(0);
|
|
1268
|
-
act(() => {
|
|
1269
|
-
result.current(3);
|
|
1270
|
-
});
|
|
1271
|
-
expect(onUpdate).toHaveBeenCalledTimes(1);
|
|
1272
|
-
expect(onDeepUpdate).toHaveBeenCalledTimes(1);
|
|
1273
|
-
});
|
|
1274
|
-
test('empty `deps` should not update reducers', () => {
|
|
1275
|
-
const onUpdate = jest.fn();
|
|
1276
|
-
const onDeepUpdate = jest.fn();
|
|
1277
|
-
const { result } = renderHook(() => {
|
|
1278
|
-
const [extraValue, setExtraValue] = useState(0);
|
|
1279
|
-
const reducers = useUseCase(mathUseCase, { extraValue }, []);
|
|
1280
|
-
useUpdateEffect(() => {
|
|
1281
|
-
onUpdate();
|
|
1282
|
-
}, [reducers]);
|
|
1283
|
-
useDeepCompareUpdate(() => {
|
|
1284
|
-
onDeepUpdate();
|
|
1285
|
-
}, [reducers]);
|
|
1286
|
-
return setExtraValue;
|
|
1287
|
-
});
|
|
1288
|
-
expect(onUpdate).toHaveBeenCalledTimes(0);
|
|
1289
|
-
expect(onDeepUpdate).toHaveBeenCalledTimes(0);
|
|
1290
|
-
act(() => {
|
|
1291
|
-
result.current(3);
|
|
1292
|
-
});
|
|
1293
|
-
expect(onUpdate).toHaveBeenCalledTimes(0);
|
|
1294
|
-
expect(onDeepUpdate).toHaveBeenCalledTimes(0);
|
|
1295
|
-
});
|
|
1296
|
-
test('should not trigger update', () => {
|
|
1297
|
-
const onUpdate = jest.fn();
|
|
1298
|
-
render(_jsx(MathParent, { onUpdate: onUpdate }));
|
|
1299
|
-
fireEvent.click(screen.getByText(PARENT_BUTTON_TEXT));
|
|
1300
|
-
expect(onUpdate).toHaveBeenCalledTimes(0);
|
|
1145
|
+
render(_jsx(TestParentComponent, {}));
|
|
1146
|
+
expect(onNumberMount).toHaveBeenCalledWith(11);
|
|
1147
|
+
expect(onStringMount).toHaveBeenCalledWith('hello');
|
|
1148
|
+
expect(onBooleanMount).toHaveBeenCalledWith(true);
|
|
1301
1149
|
});
|
|
1302
1150
|
});
|
|
1303
|
-
describe('`useUseCase` should work
|
|
1304
|
-
test('
|
|
1305
|
-
const
|
|
1306
|
-
const
|
|
1151
|
+
describe('`useUseCase` should work the same as useContextualCoreCollection', () => {
|
|
1152
|
+
test.each([void 0, UseCaseModes.Normal])('[mode=%s]: normal mode should trigger Parent & Child to update', (mode) => {
|
|
1153
|
+
const onParentUpdate = jest.fn();
|
|
1154
|
+
const onChildUpdate = jest.fn();
|
|
1307
1155
|
const onPathChange = jest.fn();
|
|
1308
1156
|
const onUndefinedEntity = jest.fn();
|
|
1309
1157
|
const onSetPath = jest.fn(() => {
|
|
1310
1158
|
return PATH_1;
|
|
1311
1159
|
});
|
|
1312
|
-
render(_jsx("div", { children: _jsx(Parent, { onSetPath: onSetPath, children: _jsx(Child, {
|
|
1160
|
+
render(_jsx("div", { children: _jsx(Parent, { mode: mode, onSetPath: onSetPath, onUpdate: onParentUpdate, children: _jsx(Child, { onUpdate: onChildUpdate, onPathChange: onPathChange, onUndefinedEntity: onUndefinedEntity }) }) }));
|
|
1313
1161
|
fireEvent.click(screen.getByText(PARENT_BUTTON_TEXT));
|
|
1314
1162
|
expect(onSetPath).toHaveBeenCalledTimes(1);
|
|
1315
|
-
expect(
|
|
1163
|
+
expect(onParentUpdate).toHaveBeenCalledTimes(1);
|
|
1164
|
+
expect(onChildUpdate).toHaveBeenCalledTimes(1);
|
|
1316
1165
|
expect(onPathChange).toHaveBeenCalledWith(PATH_1);
|
|
1317
|
-
fireEvent.click(screen.getByText(
|
|
1166
|
+
fireEvent.click(screen.getByText(CHILD_BUTTON_TEXT));
|
|
1318
1167
|
expect(onSetPath).toHaveBeenCalledTimes(1);
|
|
1319
|
-
expect(
|
|
1320
|
-
expect(
|
|
1168
|
+
expect(onParentUpdate).toHaveBeenCalledTimes(2);
|
|
1169
|
+
expect(onChildUpdate).toHaveBeenCalledTimes(2);
|
|
1170
|
+
expect(onPathChange).toHaveBeenCalledWith(PATH_2);
|
|
1321
1171
|
expect(onUndefinedEntity).toHaveBeenCalledTimes(0);
|
|
1322
1172
|
});
|
|
1173
|
+
test.each([UseCaseModes.Stateless, UseCaseModes.StatelessGlobal])('[mode=%s]: stateless mode should not trigger Parent & Child to update', () => {
|
|
1174
|
+
const onParentUpdate = jest.fn();
|
|
1175
|
+
const onChildUpdate = jest.fn();
|
|
1176
|
+
const onSetPath = jest.fn(() => {
|
|
1177
|
+
return PATH_1;
|
|
1178
|
+
});
|
|
1179
|
+
render(_jsx("div", { children: _jsx(Parent, { mode: UseCaseModes.Stateless, onSetPath: onSetPath, onUpdate: onParentUpdate, children: _jsx(Child, { onUpdate: onChildUpdate }) }) }));
|
|
1180
|
+
fireEvent.click(screen.getByText(PARENT_BUTTON_TEXT));
|
|
1181
|
+
expect(onSetPath).toHaveBeenCalledTimes(1);
|
|
1182
|
+
expect(onParentUpdate).toHaveBeenCalledTimes(0);
|
|
1183
|
+
expect(onChildUpdate).toHaveBeenCalledTimes(0);
|
|
1184
|
+
fireEvent.click(screen.getByText(CHILD_BUTTON_TEXT));
|
|
1185
|
+
expect(onSetPath).toHaveBeenCalledTimes(1);
|
|
1186
|
+
expect(onParentUpdate).toHaveBeenCalledTimes(0);
|
|
1187
|
+
expect(onChildUpdate).toHaveBeenCalledTimes(0);
|
|
1188
|
+
});
|
|
1189
|
+
test('global mode should trigger Parent to update, but Child shoud not be updated', () => {
|
|
1190
|
+
const onParentUpdate = jest.fn();
|
|
1191
|
+
const onChildUpdate = jest.fn();
|
|
1192
|
+
const onSetPath = jest.fn(() => {
|
|
1193
|
+
return PATH_1;
|
|
1194
|
+
});
|
|
1195
|
+
render(_jsx("div", { children: _jsx(Parent, { mode: UseCaseModes.Global, onSetPath: onSetPath, onUpdate: onParentUpdate, children: _jsx(Child, { onUpdate: onChildUpdate }) }) }));
|
|
1196
|
+
fireEvent.click(screen.getByText(PARENT_BUTTON_TEXT));
|
|
1197
|
+
expect(onSetPath).toHaveBeenCalledTimes(1);
|
|
1198
|
+
expect(onParentUpdate).toHaveBeenCalledTimes(1);
|
|
1199
|
+
expect(onChildUpdate).toHaveBeenCalledTimes(0);
|
|
1200
|
+
fireEvent.click(screen.getByText(CHILD_BUTTON_TEXT));
|
|
1201
|
+
expect(onSetPath).toHaveBeenCalledTimes(1);
|
|
1202
|
+
expect(onParentUpdate).toHaveBeenCalledTimes(2);
|
|
1203
|
+
expect(onChildUpdate).toHaveBeenCalledTimes(0);
|
|
1204
|
+
});
|
|
1323
1205
|
test('`usecase` should not be called at child component', () => {
|
|
1324
1206
|
const mockUseCase = jest.fn(fileUseCase);
|
|
1325
1207
|
const A = () => {
|
|
@@ -1521,4 +1403,193 @@ describe('useUseCase', () => {
|
|
|
1521
1403
|
expect(onChangeC).toHaveReturnedWith(3);
|
|
1522
1404
|
});
|
|
1523
1405
|
});
|
|
1406
|
+
describe('`useUseCase` should work the same as `useReducers`', () => {
|
|
1407
|
+
test('`entity` should equal `defaultFile`', () => {
|
|
1408
|
+
const { result } = renderHook(() => {
|
|
1409
|
+
return useUseCase(mathUseCase);
|
|
1410
|
+
});
|
|
1411
|
+
const { current: reducers } = result;
|
|
1412
|
+
expect(Array.isArray(reducers)).toBe(false);
|
|
1413
|
+
});
|
|
1414
|
+
test('returned reducer should work', () => {
|
|
1415
|
+
const { result } = renderHook(() => {
|
|
1416
|
+
return useUseCase(mathUseCase);
|
|
1417
|
+
});
|
|
1418
|
+
const { current: reducers } = result;
|
|
1419
|
+
const { add } = reducers;
|
|
1420
|
+
expect(add(1, 2)).toBe(3);
|
|
1421
|
+
});
|
|
1422
|
+
test('`usecase` should be called only once if deps has not provided', () => {
|
|
1423
|
+
const mockUseCase = jest.fn(mathUseCase);
|
|
1424
|
+
const { rerender } = renderHook(() => {
|
|
1425
|
+
return useUseCase(mockUseCase);
|
|
1426
|
+
});
|
|
1427
|
+
expect(mockUseCase).toHaveBeenCalledTimes(1);
|
|
1428
|
+
rerender();
|
|
1429
|
+
expect(mockUseCase).toHaveBeenCalledTimes(1);
|
|
1430
|
+
});
|
|
1431
|
+
test('`usecase` should be called only once if deps has not changed', () => {
|
|
1432
|
+
const mockUseCase = jest.fn(mathUseCase);
|
|
1433
|
+
const { rerender } = renderHook(() => {
|
|
1434
|
+
return useUseCase(mockUseCase, {}, [1, 'x']);
|
|
1435
|
+
});
|
|
1436
|
+
expect(mockUseCase).toHaveBeenCalledTimes(1);
|
|
1437
|
+
rerender();
|
|
1438
|
+
expect(mockUseCase).toHaveBeenCalledTimes(1);
|
|
1439
|
+
});
|
|
1440
|
+
test('`usecase` should be called if deps has changed', () => {
|
|
1441
|
+
let i = 0;
|
|
1442
|
+
const mockUseCase = jest.fn(mathUseCase);
|
|
1443
|
+
const { rerender } = renderHook(() => {
|
|
1444
|
+
return useUseCase(mockUseCase, {}, [i++, 'x']);
|
|
1445
|
+
});
|
|
1446
|
+
expect(mockUseCase).toHaveBeenCalledTimes(1);
|
|
1447
|
+
rerender();
|
|
1448
|
+
expect(mockUseCase).toHaveBeenCalledTimes(2);
|
|
1449
|
+
});
|
|
1450
|
+
test('reducer call should not be cached if component is at rendering phase', () => {
|
|
1451
|
+
const buttonText = 'button';
|
|
1452
|
+
const CacheTestComponent = () => {
|
|
1453
|
+
const { subtraction } = useUseCase(mathUseCase);
|
|
1454
|
+
const update = useUpdate();
|
|
1455
|
+
const onClick = () => {
|
|
1456
|
+
update();
|
|
1457
|
+
};
|
|
1458
|
+
subtraction(5, 3);
|
|
1459
|
+
return _jsx("button", { onClick: onClick, children: buttonText });
|
|
1460
|
+
};
|
|
1461
|
+
render(_jsx(CacheTestComponent, {}));
|
|
1462
|
+
expect(subtractionReducer).toHaveBeenCalledTimes(1);
|
|
1463
|
+
expect(subtractionReducer).toHaveBeenCalledWith(5, 3);
|
|
1464
|
+
expect(subtractionReducer).toHaveReturnedWith(2);
|
|
1465
|
+
fireEvent.click(screen.getByText(buttonText));
|
|
1466
|
+
expect(subtractionReducer).toHaveBeenCalledTimes(2);
|
|
1467
|
+
fireEvent.click(screen.getByText(buttonText));
|
|
1468
|
+
expect(subtractionReducer).toHaveBeenCalledTimes(3);
|
|
1469
|
+
});
|
|
1470
|
+
test('reducer call should not be cached if component is not at rendering phase', () => {
|
|
1471
|
+
const buttonText = 'button';
|
|
1472
|
+
const CacheTestComponent = () => {
|
|
1473
|
+
const { subtraction } = useUseCase(mathUseCase);
|
|
1474
|
+
const onClick = () => {
|
|
1475
|
+
subtraction(5, 3);
|
|
1476
|
+
};
|
|
1477
|
+
useMount(() => {
|
|
1478
|
+
subtraction(5, 3);
|
|
1479
|
+
subtraction(5, 3);
|
|
1480
|
+
});
|
|
1481
|
+
return _jsx("button", { onClick: onClick, children: buttonText });
|
|
1482
|
+
};
|
|
1483
|
+
render(_jsx(CacheTestComponent, {}));
|
|
1484
|
+
expect(subtractionReducer).toHaveBeenCalledTimes(2);
|
|
1485
|
+
expect(subtractionReducer).toHaveBeenNthCalledWith(1, 5, 3);
|
|
1486
|
+
expect(subtractionReducer).toHaveNthReturnedWith(1, 2);
|
|
1487
|
+
expect(subtractionReducer).toHaveBeenNthCalledWith(2, 5, 3);
|
|
1488
|
+
expect(subtractionReducer).toHaveNthReturnedWith(2, 2);
|
|
1489
|
+
fireEvent.click(screen.getByText(buttonText));
|
|
1490
|
+
expect(subtractionReducer).toHaveBeenCalledTimes(3);
|
|
1491
|
+
expect(subtractionReducer).toHaveBeenNthCalledWith(3, 5, 3);
|
|
1492
|
+
expect(subtractionReducer).toHaveNthReturnedWith(3, 2);
|
|
1493
|
+
});
|
|
1494
|
+
test('reducer call should not be cached if parameters have changed', () => {
|
|
1495
|
+
let count = 0;
|
|
1496
|
+
const buttonText = 'button';
|
|
1497
|
+
const StringUseCaseTestComponent = () => {
|
|
1498
|
+
const { subtraction } = useUseCase(mathUseCase);
|
|
1499
|
+
const update = useUpdate();
|
|
1500
|
+
subtraction(5, count++);
|
|
1501
|
+
const onUpdate = () => {
|
|
1502
|
+
update();
|
|
1503
|
+
};
|
|
1504
|
+
return (_jsx("div", { children: _jsx("button", { onClick: onUpdate, children: buttonText }) }));
|
|
1505
|
+
};
|
|
1506
|
+
render(_jsx(StringUseCaseTestComponent, {}));
|
|
1507
|
+
expect(subtractionReducer).toHaveBeenCalledTimes(1);
|
|
1508
|
+
expect(subtractionReducer).toHaveBeenCalledWith(5, 0);
|
|
1509
|
+
fireEvent.click(screen.getByText(buttonText));
|
|
1510
|
+
expect(subtractionReducer).toHaveBeenCalledTimes(2);
|
|
1511
|
+
expect(subtractionReducer).toHaveBeenCalledWith(5, 1);
|
|
1512
|
+
expect(subtractionReducer).toHaveReturnedWith(4);
|
|
1513
|
+
});
|
|
1514
|
+
test('`options.extraValue` should be added after call `add` method', () => {
|
|
1515
|
+
const { result } = renderHook(() => {
|
|
1516
|
+
return useUseCase(mathUseCase, { extraValue: 5 });
|
|
1517
|
+
});
|
|
1518
|
+
const { current: reducers } = result;
|
|
1519
|
+
const { add } = reducers;
|
|
1520
|
+
expect(add(1, 2)).toBe(8);
|
|
1521
|
+
});
|
|
1522
|
+
test('when `options` has changed, it should not trigger update', () => {
|
|
1523
|
+
const onUpdate = jest.fn();
|
|
1524
|
+
const onDeepUpdate = jest.fn();
|
|
1525
|
+
const { result } = renderHook(() => {
|
|
1526
|
+
const [extraValue, setExtraValue] = useState(0);
|
|
1527
|
+
const reducers = useUseCase(mathUseCase, { extraValue });
|
|
1528
|
+
useUpdateEffect(() => {
|
|
1529
|
+
onUpdate();
|
|
1530
|
+
}, [reducers]);
|
|
1531
|
+
useDeepCompareUpdate(() => {
|
|
1532
|
+
onDeepUpdate();
|
|
1533
|
+
}, [reducers]);
|
|
1534
|
+
return setExtraValue;
|
|
1535
|
+
});
|
|
1536
|
+
expect(onUpdate).toHaveBeenCalledTimes(0);
|
|
1537
|
+
expect(onDeepUpdate).toHaveBeenCalledTimes(0);
|
|
1538
|
+
act(() => {
|
|
1539
|
+
result.current(3);
|
|
1540
|
+
});
|
|
1541
|
+
expect(onUpdate).toHaveBeenCalledTimes(0);
|
|
1542
|
+
expect(onDeepUpdate).toHaveBeenCalledTimes(0);
|
|
1543
|
+
});
|
|
1544
|
+
test('when `deps` change, it should update reducers', () => {
|
|
1545
|
+
const onUpdate = jest.fn();
|
|
1546
|
+
const onDeepUpdate = jest.fn();
|
|
1547
|
+
const { result } = renderHook(() => {
|
|
1548
|
+
const [extraValue, setExtraValue] = useState(0);
|
|
1549
|
+
const reducers = useUseCase(mathUseCase, { extraValue }, [extraValue]);
|
|
1550
|
+
useUpdateEffect(() => {
|
|
1551
|
+
onUpdate();
|
|
1552
|
+
}, [reducers]);
|
|
1553
|
+
useDeepCompareUpdate(() => {
|
|
1554
|
+
onDeepUpdate();
|
|
1555
|
+
}, [reducers]);
|
|
1556
|
+
return setExtraValue;
|
|
1557
|
+
});
|
|
1558
|
+
expect(onUpdate).toHaveBeenCalledTimes(0);
|
|
1559
|
+
expect(onDeepUpdate).toHaveBeenCalledTimes(0);
|
|
1560
|
+
act(() => {
|
|
1561
|
+
result.current(3);
|
|
1562
|
+
});
|
|
1563
|
+
expect(onUpdate).toHaveBeenCalledTimes(1);
|
|
1564
|
+
expect(onDeepUpdate).toHaveBeenCalledTimes(1);
|
|
1565
|
+
});
|
|
1566
|
+
test('empty `deps` should not update reducers', () => {
|
|
1567
|
+
const onUpdate = jest.fn();
|
|
1568
|
+
const onDeepUpdate = jest.fn();
|
|
1569
|
+
const { result } = renderHook(() => {
|
|
1570
|
+
const [extraValue, setExtraValue] = useState(0);
|
|
1571
|
+
const reducers = useUseCase(mathUseCase, { extraValue }, []);
|
|
1572
|
+
useUpdateEffect(() => {
|
|
1573
|
+
onUpdate();
|
|
1574
|
+
}, [reducers]);
|
|
1575
|
+
useDeepCompareUpdate(() => {
|
|
1576
|
+
onDeepUpdate();
|
|
1577
|
+
}, [reducers]);
|
|
1578
|
+
return setExtraValue;
|
|
1579
|
+
});
|
|
1580
|
+
expect(onUpdate).toHaveBeenCalledTimes(0);
|
|
1581
|
+
expect(onDeepUpdate).toHaveBeenCalledTimes(0);
|
|
1582
|
+
act(() => {
|
|
1583
|
+
result.current(3);
|
|
1584
|
+
});
|
|
1585
|
+
expect(onUpdate).toHaveBeenCalledTimes(0);
|
|
1586
|
+
expect(onDeepUpdate).toHaveBeenCalledTimes(0);
|
|
1587
|
+
});
|
|
1588
|
+
test('should not trigger update', () => {
|
|
1589
|
+
const onUpdate = jest.fn();
|
|
1590
|
+
render(_jsx(MathParent, { onUpdate: onUpdate }));
|
|
1591
|
+
fireEvent.click(screen.getByText(PARENT_BUTTON_TEXT));
|
|
1592
|
+
expect(onUpdate).toHaveBeenCalledTimes(0);
|
|
1593
|
+
});
|
|
1594
|
+
});
|
|
1524
1595
|
});
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { ContextualEntityReducers } from '../../configs/defaultUseCaseContext/types';
|
|
2
2
|
import { EntityReducers, EntityUseCase, Reducers, UseCase } from '@mic-rexjs/usecases';
|
|
3
3
|
import { UseCaseProvider } from '../useProvider/types';
|
|
4
|
-
|
|
4
|
+
import { UseCaseModes } from '../../enums/UseCaseModes';
|
|
5
|
+
export type CoreCollection<T, TEntityReducers extends EntityReducers<T>, TProvider extends UseCaseProvider | null = UseCaseProvider> = [entity: T, reducers: ContextualEntityReducers<T, TEntityReducers>, Provider: TProvider];
|
|
5
6
|
export interface EntityGetter<T> {
|
|
6
7
|
(): T;
|
|
7
8
|
}
|
|
@@ -28,24 +29,70 @@ export interface UseCaseHookContextualOptions<T> {
|
|
|
28
29
|
onChange?(newEntity: T, oldEntity: T): void;
|
|
29
30
|
}
|
|
30
31
|
export interface UseCaseHookOwnOptions<T, TUseCaseOptions extends object> extends UseCaseHookContextualOptions<T> {
|
|
31
|
-
stateless?: boolean;
|
|
32
32
|
options?: TUseCaseOptions;
|
|
33
33
|
}
|
|
34
34
|
export type UseCaseHookOptions<T, TUseCaseOptions extends object = object> = TUseCaseOptions & UseCaseHookOwnOptions<T, TUseCaseOptions>;
|
|
35
|
-
export
|
|
36
|
-
|
|
35
|
+
export type ContextualCoreCollectionHookParameters<T, TEntityReducers extends EntityReducers<T>> = [
|
|
36
|
+
usecase: EntityUseCase<T, TEntityReducers> &
|
|
37
37
|
/**
|
|
38
38
|
* 如果不使用 `&`,那么很多情况下 `options` 类型无法被正确推导;
|
|
39
39
|
* 因为使用 `&` 是为了让该参数 `usecase` 的泛型 `T` 推导占优先级,
|
|
40
40
|
* 从而保证 `options` 里的泛型 `T` 是根据 `usecase` 来推导的。
|
|
41
41
|
*/
|
|
42
|
-
UseCase<EntityReducers<T>>,
|
|
43
|
-
|
|
42
|
+
UseCase<EntityReducers<T>>,
|
|
43
|
+
options?: UseCaseHookContextualOptions<T>
|
|
44
|
+
];
|
|
45
|
+
export interface ContextualCoreCollectionHook {
|
|
46
|
+
<T, TEntityReducers extends EntityReducers<T>>(...args: ContextualCoreCollectionHookParameters<T, TEntityReducers>): CoreCollection<T, TEntityReducers, null>;
|
|
47
|
+
}
|
|
48
|
+
export type RootCoreCollectionHookParameters<T, TEntityReducers extends EntityReducers<T>, TUseCaseOptions extends object = object> = [
|
|
49
|
+
entity: T | EntityGetter<T>,
|
|
50
|
+
usecase: EntityUseCase<T, TEntityReducers, TUseCaseOptions> &
|
|
51
|
+
/**
|
|
52
|
+
* 如果不使用 `&`,那么很多情况下 `options` 类型无法被正确推导;
|
|
53
|
+
* 因为使用 `&` 是为了让该参数 `usecase` 的泛型 `T` 推导占优先级,
|
|
54
|
+
* 从而保证 `options` 里的泛型 `T` 是根据 `usecase` 来推导的。
|
|
55
|
+
*/
|
|
56
|
+
UseCase<EntityReducers<T>, TUseCaseOptions>,
|
|
57
|
+
options?: UseCaseHookOptions<T, TUseCaseOptions>,
|
|
58
|
+
deps?: unknown[]
|
|
59
|
+
];
|
|
60
|
+
export interface RootCoreCollectionHook {
|
|
61
|
+
<T, TEntityReducers extends EntityReducers<T>, TUseCaseOptions extends object = object>(...args: RootCoreCollectionHookParameters<T, TEntityReducers, TUseCaseOptions>): CoreCollection<T, TEntityReducers>;
|
|
62
|
+
}
|
|
63
|
+
export type ModeCoreCollectionHookParameters<T, TEntityReducers extends EntityReducers<T>, TUseCaseOptions extends object = object> = [
|
|
64
|
+
entity: T | EntityGetter<T>,
|
|
65
|
+
usecase: EntityUseCase<T, TEntityReducers, TUseCaseOptions> &
|
|
44
66
|
/**
|
|
45
67
|
* 如果不使用 `&`,那么很多情况下 `options` 类型无法被正确推导;
|
|
46
68
|
* 因为使用 `&` 是为了让该参数 `usecase` 的泛型 `T` 推导占优先级,
|
|
47
69
|
* 从而保证 `options` 里的泛型 `T` 是根据 `usecase` 来推导的。
|
|
48
70
|
*/
|
|
49
|
-
UseCase<EntityReducers<T>, TUseCaseOptions>,
|
|
50
|
-
|
|
71
|
+
UseCase<EntityReducers<T>, TUseCaseOptions>,
|
|
72
|
+
mode?: UseCaseModes,
|
|
73
|
+
options?: UseCaseHookOptions<T, TUseCaseOptions>,
|
|
74
|
+
deps?: unknown[]
|
|
75
|
+
];
|
|
76
|
+
export interface ModeCoreCollectionHook {
|
|
77
|
+
<T, TEntityReducers extends EntityReducers<T>, TUseCaseOptions extends object = object>(...args: ModeCoreCollectionHookParameters<T, TEntityReducers, TUseCaseOptions>): CoreCollection<T, TEntityReducers>;
|
|
78
|
+
}
|
|
79
|
+
export interface CoreCollectionHook extends ContextualCoreCollectionHook, RootCoreCollectionHook, ModeCoreCollectionHook {
|
|
80
|
+
}
|
|
81
|
+
export type ReducersHookParameters<T extends Reducers, TUseCaseOptions extends object = object> = [
|
|
82
|
+
usecase: UseCase<T, TUseCaseOptions>,
|
|
83
|
+
options?: TUseCaseOptions,
|
|
84
|
+
deps?: unknown[]
|
|
85
|
+
];
|
|
86
|
+
export interface ReducersHook {
|
|
87
|
+
<T extends Reducers, TUseCaseOptions extends object = object>(...args: ReducersHookParameters<T, TUseCaseOptions>): T;
|
|
88
|
+
}
|
|
89
|
+
export type UseCaseHookParameters<T, TReducers extends Reducers, TEntityReducers extends EntityReducers<T>, TUseCaseOptions extends object> = ContextualCoreCollectionHookParameters<T, TEntityReducers> | RootCoreCollectionHookParameters<T, TEntityReducers, TUseCaseOptions> | ModeCoreCollectionHookParameters<T, TEntityReducers, TUseCaseOptions> | ReducersHookParameters<TReducers, TUseCaseOptions>;
|
|
90
|
+
export type UseCaseHookMaxParameters<T, TReducers extends Reducers, TEntityReducers extends EntityReducers<T>, TUseCaseOptions extends object> = [
|
|
91
|
+
entity: T | EntityGetter<T> | null,
|
|
92
|
+
usecase: UseCase<TReducers, TUseCaseOptions> | EntityUseCase<T, TEntityReducers, TUseCaseOptions>,
|
|
93
|
+
mode: UseCaseModes,
|
|
94
|
+
options: TUseCaseOptions | UseCaseHookOptions<T, TUseCaseOptions> | UseCaseHookContextualOptions<T>,
|
|
95
|
+
deps: unknown[]
|
|
96
|
+
];
|
|
97
|
+
export interface UseCaseHook extends CoreCollectionHook, ReducersHook {
|
|
51
98
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { EntityReducers, EntityUseCase } from '@mic-rexjs/usecases';
|
|
2
|
-
import {
|
|
3
|
-
export declare const useUseCaseContext: <T, TEntityReducers extends EntityReducers<T>, TUseCaseOptions extends object, TContext extends
|
|
2
|
+
import { UseCaseContext } from '../../configs/defaultUseCaseContext/types';
|
|
3
|
+
export declare const useUseCaseContext: <T, TEntityReducers extends EntityReducers<T>, TUseCaseOptions extends object, TContext extends UseCaseContext<T, TEntityReducers> = UseCaseContext<T, TEntityReducers>>(usecase: EntityUseCase<T, TEntityReducers, TUseCaseOptions>, defaultContext?: TContext | null | undefined) => TContext;
|