@mic-rexjs/usecases-react 1.3.36 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.min.js +1 -1
- package/es/components/UpdateFragment/index.d.ts +2 -0
- package/es/components/UpdateFragment/index.js +8 -0
- package/es/components/UpdateFragment/types.d.ts +3 -0
- package/es/components/UseCaseFragment/index.d.ts +1 -1
- package/es/components/UseCaseFragment/types.d.ts +2 -2
- package/es/configs/defaultUseCaseContext/index.d.ts +3 -1
- package/es/configs/defaultUseCaseContext/index.js +1 -1
- package/es/configs/defaultUseCaseContext/types.d.ts +11 -0
- package/es/configs/defaultUseCaseContext/types.js +1 -0
- package/es/configs/usecaseContextMap/index.d.ts +1 -3
- package/es/configs/usecaseContextMap/types.d.ts +4 -17
- package/es/hooks/useCompareDeps/index.d.ts +1 -0
- package/es/hooks/useCompareDeps/index.js +24 -0
- package/es/hooks/useConstant/index.d.ts +2 -0
- package/es/hooks/useConstant/index.js +5 -0
- package/es/hooks/useConstant/types.d.ts +3 -0
- package/es/hooks/useConstant/types.js +1 -0
- package/es/hooks/useConstantFn/index.d.ts +1 -0
- package/es/hooks/useConstantFn/index.js +7 -0
- package/es/hooks/useOptionsRefCollection/index.d.ts +3 -0
- package/es/hooks/useOptionsRefCollection/index.js +22 -0
- package/es/hooks/useOptionsRefCollection/types.d.ts +2 -0
- package/es/hooks/useOptionsRefCollection/types.js +1 -0
- package/es/hooks/useProvider/index.d.ts +7 -0
- package/es/hooks/useProvider/index.js +17 -0
- package/es/hooks/useProvider/types.d.ts +3 -0
- package/es/hooks/useProvider/types.js +1 -0
- package/es/hooks/useScope/index.d.ts +2 -0
- package/es/hooks/useScope/index.js +3 -0
- package/es/hooks/useScope/types.d.ts +3 -0
- package/es/hooks/useScope/types.js +1 -0
- package/es/hooks/useUseCase/index.js +68 -89
- package/es/hooks/useUseCase/index.test.js +166 -136
- package/es/hooks/useUseCase/types.d.ts +9 -7
- package/es/hooks/useUseCaseContext/index.d.ts +3 -0
- package/es/hooks/useUseCaseContext/index.js +17 -0
- package/es/index.d.ts +3 -2
- package/es/methods/getRootEntity/index.d.ts +2 -0
- package/es/methods/getRootEntity/index.js +9 -0
- package/es/methods/initEntityReducers/index.d.ts +5 -0
- package/es/methods/initEntityReducers/index.js +13 -0
- package/es/methods/initEntityReducers/types.d.ts +3 -0
- package/es/methods/initEntityReducers/types.js +1 -0
- package/es/methods/removeItem/index.d.ts +1 -0
- package/es/methods/removeItem/index.js +7 -0
- package/es/methods/triggerCallbacks/index.d.ts +3 -0
- package/es/methods/triggerCallbacks/index.js +14 -0
- package/es/{hooks/useUseCase/methods → methods}/triggerWatchers/index.d.ts +1 -1
- package/lib/components/UpdateFragment/index.js +16 -0
- package/lib/configs/defaultUseCaseContext/index.js +1 -1
- package/lib/configs/defaultUseCaseContext/types.js +5 -0
- package/lib/hooks/useCompareDeps/index.js +31 -0
- package/lib/hooks/useConstant/index.js +16 -0
- package/lib/hooks/useConstant/types.js +5 -0
- package/lib/hooks/useConstantFn/index.js +18 -0
- package/lib/hooks/useOptionsRefCollection/index.js +29 -0
- package/lib/hooks/useOptionsRefCollection/types.js +5 -0
- package/lib/hooks/useProvider/index.js +30 -0
- package/lib/hooks/useProvider/types.js +5 -0
- package/lib/hooks/useScope/index.js +10 -0
- package/lib/hooks/useScope/types.js +5 -0
- package/lib/hooks/useUseCase/index.js +73 -115
- package/lib/hooks/useUseCase/index.test.js +226 -177
- package/lib/hooks/useUseCaseContext/index.js +24 -0
- package/lib/methods/getRootEntity/index.js +16 -0
- package/lib/methods/initEntityReducers/index.js +29 -0
- package/lib/methods/initEntityReducers/types.js +5 -0
- package/lib/methods/removeItem/index.js +14 -0
- package/lib/methods/triggerCallbacks/index.js +22 -0
- package/package.json +2 -2
- package/es/core/usecases/optionsGetterCellectionUseCase/index.d.ts +0 -2
- package/es/core/usecases/optionsGetterCellectionUseCase/index.js +0 -13
- package/es/core/usecases/optionsGetterCellectionUseCase/types.d.ts +0 -8
- package/es/hooks/useOptionsTransfer/index.d.ts +0 -3
- package/es/hooks/useOptionsTransfer/index.js +0 -15
- package/es/hooks/useUseCase/methods/triggerCallbacks/index.d.ts +0 -3
- package/es/hooks/useUseCase/methods/triggerCallbacks/index.js +0 -11
- package/lib/core/usecases/optionsGetterCellectionUseCase/index.js +0 -23
- package/lib/hooks/useOptionsTransfer/index.js +0 -23
- package/lib/hooks/useUseCase/methods/triggerCallbacks/index.js +0 -32
- /package/es/{core/usecases/optionsGetterCellectionUseCase → components/UpdateFragment}/types.js +0 -0
- /package/es/{hooks/useUseCase/methods → methods}/triggerWatchers/index.js +0 -0
- /package/lib/{core/usecases/optionsGetterCellectionUseCase → components/UpdateFragment}/types.js +0 -0
- /package/lib/{hooks/useUseCase/methods → methods}/triggerWatchers/index.js +0 -0
|
@@ -294,6 +294,7 @@ describe('useUseCase', () => {
|
|
|
294
294
|
const { result } = renderHook(() => {
|
|
295
295
|
return useUseCase(defaultFile, fileUseCase, { onChange });
|
|
296
296
|
});
|
|
297
|
+
``;
|
|
297
298
|
const { current: context } = result;
|
|
298
299
|
const [, reducers] = context;
|
|
299
300
|
const { setPath } = reducers;
|
|
@@ -414,72 +415,122 @@ describe('useUseCase', () => {
|
|
|
414
415
|
expect(onDeepUpdate).toHaveBeenCalledTimes(0);
|
|
415
416
|
});
|
|
416
417
|
});
|
|
417
|
-
describe('`useUseCase` should work with 1+
|
|
418
|
-
test('
|
|
418
|
+
describe('`useUseCase` should work with 1+ arguments on non-entity mode', () => {
|
|
419
|
+
test('`entity` should equal `defaultFile`', () => {
|
|
419
420
|
const { result } = renderHook(() => {
|
|
420
|
-
return useUseCase(
|
|
421
|
+
return useUseCase(mathUseCase);
|
|
421
422
|
});
|
|
422
|
-
const { current:
|
|
423
|
-
expect(
|
|
423
|
+
const { current: reducers } = result;
|
|
424
|
+
expect(Array.isArray(reducers)).toBe(false);
|
|
424
425
|
});
|
|
425
|
-
test('
|
|
426
|
+
test('returned reducer should work', () => {
|
|
426
427
|
const { result } = renderHook(() => {
|
|
427
|
-
return useUseCase(
|
|
428
|
+
return useUseCase(mathUseCase);
|
|
428
429
|
});
|
|
429
|
-
const { current:
|
|
430
|
-
const
|
|
431
|
-
expect(
|
|
430
|
+
const { current: reducers } = result;
|
|
431
|
+
const { add } = reducers;
|
|
432
|
+
expect(add(1, 2)).toBe(3);
|
|
432
433
|
});
|
|
433
|
-
test('`
|
|
434
|
+
test('`options.extraValue` should be added after call `add` method', () => {
|
|
434
435
|
const { result } = renderHook(() => {
|
|
435
|
-
return useUseCase(
|
|
436
|
+
return useUseCase(mathUseCase, { extraValue: 5 });
|
|
436
437
|
});
|
|
437
|
-
const { current:
|
|
438
|
-
const
|
|
439
|
-
expect(
|
|
438
|
+
const { current: reducers } = result;
|
|
439
|
+
const { add } = reducers;
|
|
440
|
+
expect(add(1, 2)).toBe(8);
|
|
440
441
|
});
|
|
441
|
-
test('
|
|
442
|
+
test('when `options` has changed, it should not trigger update', () => {
|
|
442
443
|
const onUpdate = jest.fn();
|
|
444
|
+
const onDeepUpdate = jest.fn();
|
|
443
445
|
const { result } = renderHook(() => {
|
|
446
|
+
const [extraValue, setExtraValue] = useState(0);
|
|
447
|
+
const reducers = useUseCase(mathUseCase, { extraValue });
|
|
444
448
|
useUpdateEffect(() => {
|
|
445
449
|
onUpdate();
|
|
446
|
-
});
|
|
447
|
-
|
|
450
|
+
}, [reducers]);
|
|
451
|
+
useDeepCompareUpdate(() => {
|
|
452
|
+
onDeepUpdate();
|
|
453
|
+
}, [reducers]);
|
|
454
|
+
return setExtraValue;
|
|
448
455
|
});
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
const { setPath } = reducers;
|
|
456
|
+
expect(onUpdate).toHaveBeenCalledTimes(0);
|
|
457
|
+
expect(onDeepUpdate).toHaveBeenCalledTimes(0);
|
|
452
458
|
act(() => {
|
|
453
|
-
|
|
459
|
+
result.current(3);
|
|
454
460
|
});
|
|
455
|
-
expect(result.current).toBe(context);
|
|
456
|
-
expect(result.current).toEqual(context);
|
|
457
461
|
expect(onUpdate).toHaveBeenCalledTimes(0);
|
|
462
|
+
expect(onDeepUpdate).toHaveBeenCalledTimes(0);
|
|
458
463
|
});
|
|
459
|
-
test('
|
|
464
|
+
test('when `deps` change, it should update reducers', () => {
|
|
465
|
+
const onUpdate = jest.fn();
|
|
466
|
+
const onDeepUpdate = jest.fn();
|
|
467
|
+
const { result } = renderHook(() => {
|
|
468
|
+
const [extraValue, setExtraValue] = useState(0);
|
|
469
|
+
const reducers = useUseCase(mathUseCase, { extraValue }, [extraValue]);
|
|
470
|
+
useUpdateEffect(() => {
|
|
471
|
+
onUpdate();
|
|
472
|
+
}, [reducers]);
|
|
473
|
+
useDeepCompareUpdate(() => {
|
|
474
|
+
onDeepUpdate();
|
|
475
|
+
}, [reducers]);
|
|
476
|
+
return setExtraValue;
|
|
477
|
+
});
|
|
478
|
+
expect(onUpdate).toHaveBeenCalledTimes(0);
|
|
479
|
+
expect(onDeepUpdate).toHaveBeenCalledTimes(0);
|
|
480
|
+
act(() => {
|
|
481
|
+
result.current(3);
|
|
482
|
+
});
|
|
483
|
+
expect(onUpdate).toHaveBeenCalledTimes(1);
|
|
484
|
+
expect(onDeepUpdate).toHaveBeenCalledTimes(1);
|
|
485
|
+
});
|
|
486
|
+
test('empty `deps` should not update reducers', () => {
|
|
487
|
+
const onUpdate = jest.fn();
|
|
488
|
+
const onDeepUpdate = jest.fn();
|
|
489
|
+
const { result } = renderHook(() => {
|
|
490
|
+
const [extraValue, setExtraValue] = useState(0);
|
|
491
|
+
const reducers = useUseCase(mathUseCase, { extraValue }, []);
|
|
492
|
+
useUpdateEffect(() => {
|
|
493
|
+
onUpdate();
|
|
494
|
+
}, [reducers]);
|
|
495
|
+
useDeepCompareUpdate(() => {
|
|
496
|
+
onDeepUpdate();
|
|
497
|
+
}, [reducers]);
|
|
498
|
+
return setExtraValue;
|
|
499
|
+
});
|
|
500
|
+
expect(onUpdate).toHaveBeenCalledTimes(0);
|
|
501
|
+
expect(onDeepUpdate).toHaveBeenCalledTimes(0);
|
|
502
|
+
act(() => {
|
|
503
|
+
result.current(3);
|
|
504
|
+
});
|
|
505
|
+
expect(onUpdate).toHaveBeenCalledTimes(0);
|
|
506
|
+
expect(onDeepUpdate).toHaveBeenCalledTimes(0);
|
|
507
|
+
});
|
|
508
|
+
test('should not trigger update', () => {
|
|
509
|
+
const onUpdate = jest.fn();
|
|
510
|
+
render(_jsx(MathParent, { onUpdate: onUpdate }));
|
|
511
|
+
fireEvent.click(screen.getByText(PARENT_BUTTON_TEXT));
|
|
512
|
+
expect(onUpdate).toHaveBeenCalledTimes(0);
|
|
513
|
+
});
|
|
514
|
+
});
|
|
515
|
+
describe('`useUseCase` should work with 1+ arguments on context mode', () => {
|
|
516
|
+
test('should work within <Child /> which it is under <Parent />', () => {
|
|
460
517
|
const textPrefix = '>>';
|
|
461
|
-
const
|
|
462
|
-
const
|
|
463
|
-
const
|
|
464
|
-
const onUpdate2 = jest.fn();
|
|
465
|
-
const onPathChange2 = jest.fn();
|
|
466
|
-
const onUndefinedEntity2 = jest.fn();
|
|
518
|
+
const onUpdate = jest.fn();
|
|
519
|
+
const onPathChange = jest.fn();
|
|
520
|
+
const onUndefinedEntity = jest.fn();
|
|
467
521
|
const onSetPath = jest.fn(() => {
|
|
468
522
|
return PATH_1;
|
|
469
523
|
});
|
|
470
|
-
render(
|
|
524
|
+
render(_jsx("div", { children: _jsx(Parent, { onSetPath: onSetPath, children: _jsx(Child, { textPrefix: textPrefix, onUpdate: onUpdate, onPathChange: onPathChange, onUndefinedEntity: onUndefinedEntity }) }) }));
|
|
471
525
|
fireEvent.click(screen.getByText(PARENT_BUTTON_TEXT));
|
|
472
526
|
expect(onSetPath).toHaveBeenCalledTimes(1);
|
|
473
|
-
expect(
|
|
474
|
-
expect(
|
|
527
|
+
expect(onUpdate).toHaveBeenCalledTimes(1);
|
|
528
|
+
expect(onPathChange).toHaveBeenCalledWith(PATH_1);
|
|
475
529
|
fireEvent.click(screen.getByText(textPrefix + CHILD_BUTTON_TEXT));
|
|
476
530
|
expect(onSetPath).toHaveBeenCalledTimes(1);
|
|
477
|
-
expect(
|
|
478
|
-
expect(
|
|
479
|
-
expect(
|
|
480
|
-
expect(onPathChange2).toHaveBeenCalledTimes(0);
|
|
481
|
-
expect(onUndefinedEntity1).toHaveBeenCalledTimes(0);
|
|
482
|
-
expect(onUndefinedEntity2).toHaveBeenCalledTimes(1);
|
|
531
|
+
expect(onUpdate).toHaveBeenCalledTimes(2);
|
|
532
|
+
expect(onPathChange).toHaveBeenCalledWith('');
|
|
533
|
+
expect(onUndefinedEntity).toHaveBeenCalledTimes(0);
|
|
483
534
|
});
|
|
484
535
|
test('`options.onChange` event should be trigger at child elements', () => {
|
|
485
536
|
const onFirstChange = jest.fn();
|
|
@@ -522,6 +573,39 @@ describe('useUseCase', () => {
|
|
|
522
573
|
expect(onFirstChange).toHaveBeenCalledTimes(1);
|
|
523
574
|
expect(onParentPathChange).toHaveBeenCalledTimes(2);
|
|
524
575
|
});
|
|
576
|
+
test('`options.onChange` event should be trigger in orders', () => {
|
|
577
|
+
let changeTimes = 0;
|
|
578
|
+
const updateChangeTimes = () => {
|
|
579
|
+
return ++changeTimes;
|
|
580
|
+
};
|
|
581
|
+
const onChangeA = jest.fn(updateChangeTimes);
|
|
582
|
+
const onChangeB = jest.fn(updateChangeTimes);
|
|
583
|
+
const onChangeC = jest.fn(updateChangeTimes);
|
|
584
|
+
const buttonText = 'my button';
|
|
585
|
+
const A = ({ children }) => {
|
|
586
|
+
useUseCase(fileUseCase, { onChange: onChangeA });
|
|
587
|
+
return _jsx(Fragment, { children: children });
|
|
588
|
+
};
|
|
589
|
+
const B = () => {
|
|
590
|
+
useUseCase(fileUseCase, { onChange: onChangeB });
|
|
591
|
+
return _jsx(Fragment, {});
|
|
592
|
+
};
|
|
593
|
+
const C = () => {
|
|
594
|
+
const [, { setPath }, Provider] = useUseCase(defaultFile, fileUseCase, {
|
|
595
|
+
onChange: onChangeC,
|
|
596
|
+
});
|
|
597
|
+
const onFirstClick = () => {
|
|
598
|
+
setPath(PATH_1);
|
|
599
|
+
};
|
|
600
|
+
return (_jsxs(Provider, { children: [_jsx(A, { children: _jsx(B, {}) }), _jsx("button", { onClick: onFirstClick, children: buttonText })] }));
|
|
601
|
+
};
|
|
602
|
+
render(_jsx(C, {}));
|
|
603
|
+
expect(changeTimes).toBe(0);
|
|
604
|
+
fireEvent.click(screen.getByText(buttonText));
|
|
605
|
+
expect(onChangeA).toHaveReturnedWith(2);
|
|
606
|
+
expect(onChangeB).toHaveReturnedWith(1);
|
|
607
|
+
expect(onChangeC).toHaveReturnedWith(3);
|
|
608
|
+
});
|
|
525
609
|
test('`options.watch` should be trigger at child elements', () => {
|
|
526
610
|
const onFirstExtChange = jest.fn();
|
|
527
611
|
const onSecondExtChange = jest.fn();
|
|
@@ -569,102 +653,48 @@ describe('useUseCase', () => {
|
|
|
569
653
|
expect(onFirstExtChange).toHaveBeenCalledTimes(1);
|
|
570
654
|
expect(onParentExtChange).toHaveBeenCalledTimes(2);
|
|
571
655
|
});
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
const
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
expect(
|
|
612
|
-
expect(
|
|
613
|
-
|
|
614
|
-
result.current(3);
|
|
615
|
-
});
|
|
616
|
-
expect(onUpdate).toHaveBeenCalledTimes(0);
|
|
617
|
-
expect(onDeepUpdate).toHaveBeenCalledTimes(0);
|
|
618
|
-
});
|
|
619
|
-
test('when `deps` change, it should update reducers', () => {
|
|
620
|
-
const onUpdate = jest.fn();
|
|
621
|
-
const onDeepUpdate = jest.fn();
|
|
622
|
-
const { result } = renderHook(() => {
|
|
623
|
-
const [extraValue, setExtraValue] = useState(0);
|
|
624
|
-
const reducers = useUseCase(mathUseCase, { extraValue }, [extraValue]);
|
|
625
|
-
useUpdateEffect(() => {
|
|
626
|
-
onUpdate();
|
|
627
|
-
}, [reducers]);
|
|
628
|
-
useDeepCompareUpdate(() => {
|
|
629
|
-
onDeepUpdate();
|
|
630
|
-
}, [reducers]);
|
|
631
|
-
return setExtraValue;
|
|
632
|
-
});
|
|
633
|
-
expect(onUpdate).toHaveBeenCalledTimes(0);
|
|
634
|
-
expect(onDeepUpdate).toHaveBeenCalledTimes(0);
|
|
635
|
-
act(() => {
|
|
636
|
-
result.current(3);
|
|
637
|
-
});
|
|
638
|
-
expect(onUpdate).toHaveBeenCalledTimes(1);
|
|
639
|
-
expect(onDeepUpdate).toHaveBeenCalledTimes(1);
|
|
640
|
-
});
|
|
641
|
-
test('empty `deps` should not update reducers', () => {
|
|
642
|
-
const onUpdate = jest.fn();
|
|
643
|
-
const onDeepUpdate = jest.fn();
|
|
644
|
-
const { result } = renderHook(() => {
|
|
645
|
-
const [extraValue, setExtraValue] = useState(0);
|
|
646
|
-
const reducers = useUseCase(mathUseCase, { extraValue }, []);
|
|
647
|
-
useUpdateEffect(() => {
|
|
648
|
-
onUpdate();
|
|
649
|
-
}, [reducers]);
|
|
650
|
-
useDeepCompareUpdate(() => {
|
|
651
|
-
onDeepUpdate();
|
|
652
|
-
}, [reducers]);
|
|
653
|
-
return setExtraValue;
|
|
654
|
-
});
|
|
655
|
-
expect(onUpdate).toHaveBeenCalledTimes(0);
|
|
656
|
-
expect(onDeepUpdate).toHaveBeenCalledTimes(0);
|
|
657
|
-
act(() => {
|
|
658
|
-
result.current(3);
|
|
659
|
-
});
|
|
660
|
-
expect(onUpdate).toHaveBeenCalledTimes(0);
|
|
661
|
-
expect(onDeepUpdate).toHaveBeenCalledTimes(0);
|
|
662
|
-
});
|
|
663
|
-
test('should not trigger update', () => {
|
|
664
|
-
const onUpdate = jest.fn();
|
|
665
|
-
render(_jsx(MathParent, { onUpdate: onUpdate }));
|
|
666
|
-
fireEvent.click(screen.getByText(PARENT_BUTTON_TEXT));
|
|
667
|
-
expect(onUpdate).toHaveBeenCalledTimes(0);
|
|
656
|
+
test('`options.watch` should be trigger in orders', () => {
|
|
657
|
+
let changeTimes = 0;
|
|
658
|
+
const updateChangeTimes = () => {
|
|
659
|
+
return ++changeTimes;
|
|
660
|
+
};
|
|
661
|
+
const onChangeA = jest.fn(updateChangeTimes);
|
|
662
|
+
const onChangeB = jest.fn(updateChangeTimes);
|
|
663
|
+
const onChangeC = jest.fn(updateChangeTimes);
|
|
664
|
+
const buttonText = 'my button';
|
|
665
|
+
const A = ({ children }) => {
|
|
666
|
+
useUseCase(fileUseCase, {
|
|
667
|
+
watch: {
|
|
668
|
+
ext: onChangeA,
|
|
669
|
+
},
|
|
670
|
+
});
|
|
671
|
+
return _jsx(Fragment, { children: children });
|
|
672
|
+
};
|
|
673
|
+
const B = () => {
|
|
674
|
+
useUseCase(fileUseCase, {
|
|
675
|
+
watch: {
|
|
676
|
+
ext: onChangeB,
|
|
677
|
+
},
|
|
678
|
+
});
|
|
679
|
+
return _jsx(Fragment, {});
|
|
680
|
+
};
|
|
681
|
+
const C = () => {
|
|
682
|
+
const [, { setPath }, Provider] = useUseCase(defaultFile, fileUseCase, {
|
|
683
|
+
watch: {
|
|
684
|
+
ext: onChangeC,
|
|
685
|
+
},
|
|
686
|
+
});
|
|
687
|
+
const onFirstClick = () => {
|
|
688
|
+
setPath(PATH_1);
|
|
689
|
+
};
|
|
690
|
+
return (_jsxs(Provider, { children: [_jsx(A, { children: _jsx(B, {}) }), _jsx("button", { onClick: onFirstClick, children: buttonText })] }));
|
|
691
|
+
};
|
|
692
|
+
render(_jsx(C, {}));
|
|
693
|
+
expect(changeTimes).toBe(0);
|
|
694
|
+
fireEvent.click(screen.getByText(buttonText));
|
|
695
|
+
expect(onChangeA).toHaveReturnedWith(2);
|
|
696
|
+
expect(onChangeB).toHaveReturnedWith(1);
|
|
697
|
+
expect(onChangeC).toHaveReturnedWith(3);
|
|
668
698
|
});
|
|
669
699
|
});
|
|
670
700
|
});
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { ContextualEntityReducers } from '../../configs/defaultUseCaseContext/types';
|
|
1
2
|
import { EntityReducers, EntityUseCase, Reducers, UseCase } from '@mic-rexjs/usecases';
|
|
2
|
-
import {
|
|
3
|
+
import { UseCaseProvider } from '../useProvider/types';
|
|
4
|
+
export type CoreCollection<T, TEntityReducers extends EntityReducers<T>, TProvide extends UseCaseProvider | null = UseCaseProvider> = [entity: T, reducers: ContextualEntityReducers<T, TEntityReducers>, Provider: TProvide];
|
|
3
5
|
export interface EntityGetter<T> {
|
|
4
6
|
(): T;
|
|
5
7
|
}
|
|
@@ -13,13 +15,13 @@ export interface UseCaseHookContextualOptions<T> {
|
|
|
13
15
|
watch?: EntityWatchMap<T>;
|
|
14
16
|
onChange?(newEntity: T, prevEntity: T): void;
|
|
15
17
|
}
|
|
16
|
-
export interface UseCaseHookOwnOptions<T,
|
|
18
|
+
export interface UseCaseHookOwnOptions<T, TUseCaseOptions extends object> extends UseCaseHookContextualOptions<T> {
|
|
17
19
|
stateless?: boolean;
|
|
18
|
-
options?:
|
|
20
|
+
options?: TUseCaseOptions;
|
|
19
21
|
}
|
|
20
|
-
export type UseCaseHookOptions<T,
|
|
22
|
+
export type UseCaseHookOptions<T, TUseCaseOptions extends object = object> = TUseCaseOptions & UseCaseHookOwnOptions<T, TUseCaseOptions>;
|
|
21
23
|
export interface UseCaseHook {
|
|
22
|
-
<T,
|
|
23
|
-
<T,
|
|
24
|
-
<T extends Reducers,
|
|
24
|
+
<T, TEntityReducers extends EntityReducers<T>>(usecase: EntityUseCase<T, TEntityReducers & EntityReducers<T>> & UseCase<TEntityReducers>, options?: UseCaseHookContextualOptions<T>): CoreCollection<T, TEntityReducers, null>;
|
|
25
|
+
<T, TEntityReducers extends EntityReducers<T>, TUseCaseOptions extends object = object>(initailEntity: T | EntityGetter<T>, usecase: EntityUseCase<T, TEntityReducers, TUseCaseOptions> & UseCase<TEntityReducers, TUseCaseOptions>, options?: UseCaseHookOptions<T, TUseCaseOptions>, deps?: unknown[]): CoreCollection<T, TEntityReducers>;
|
|
26
|
+
<T extends Reducers, TUseCaseOptions extends object = object>(usecase: UseCase<T, TUseCaseOptions>, options?: TUseCaseOptions, deps?: unknown[]): T;
|
|
25
27
|
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { EntityReducers, EntityUseCase } from '@mic-rexjs/usecases';
|
|
2
|
+
import { UseCaseMappingContext } from '../../configs/usecaseContextMap/types';
|
|
3
|
+
export declare const useUseCaseContext: <T, TEntityReducers extends EntityReducers<T>, TUseCaseOptions extends object, TContext extends UseCaseMappingContext<T, TEntityReducers, TUseCaseOptions> = UseCaseMappingContext<T, TEntityReducers, TUseCaseOptions>>(usecase: EntityUseCase<T, TEntityReducers, TUseCaseOptions>, defaultContext?: TContext | null | undefined) => TContext;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { useConstant } from '../useConstant';
|
|
2
|
+
import { usecaseContextMap } from '../../configs/usecaseContextMap';
|
|
3
|
+
import { createContext } from 'react';
|
|
4
|
+
export const useUseCaseContext = (usecase, defaultContext) => {
|
|
5
|
+
return useConstant(() => {
|
|
6
|
+
const map = usecaseContextMap;
|
|
7
|
+
if (map.has(usecase)) {
|
|
8
|
+
return map.get(usecase);
|
|
9
|
+
}
|
|
10
|
+
if (defaultContext) {
|
|
11
|
+
return defaultContext;
|
|
12
|
+
}
|
|
13
|
+
const ctx = createContext({});
|
|
14
|
+
map.set(usecase, ctx);
|
|
15
|
+
return ctx;
|
|
16
|
+
});
|
|
17
|
+
};
|
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 type {
|
|
4
|
-
export type { UseCaseContext, UseCaseContextWithProvider, UseCaseProvider } from './configs/usecaseContextMap/types';
|
|
3
|
+
export type { CoreCollection } from './hooks/useUseCase/types';
|
|
5
4
|
export type { UseCaseHookOptions } from './hooks/useUseCase/types';
|
|
5
|
+
export type { UseCaseProvider } from './hooks/useProvider/types';
|
|
6
|
+
export type { UseCaseFragmentProps } from './components/UseCaseFragment/types';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { EntityReducers, EntityUseCase } from '@mic-rexjs/usecases';
|
|
2
|
+
import { UseCaseHookOptions } from '../../hooks/useUseCase/types';
|
|
3
|
+
import { ContextualEntityReducers } from '../../configs/defaultUseCaseContext/types';
|
|
4
|
+
import { EntityChangeEventHandler } from './types';
|
|
5
|
+
export declare const initEntityReducers: <T, TEntityReducers extends EntityReducers<T>, TUseCaseOptions extends object = object>(entity: T, usecase: EntityUseCase<T, TEntityReducers, TUseCaseOptions>, options: UseCaseHookOptions<T, TUseCaseOptions>, onEntityChange: EntityChangeEventHandler<T>) => ContextualEntityReducers<T, TEntityReducers>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { entityReducerUseCase } from '@mic-rexjs/usecases';
|
|
2
|
+
export const initEntityReducers = (entity, usecase, options, onEntityChange) => {
|
|
3
|
+
const { createEntityReducers } = entityReducerUseCase();
|
|
4
|
+
const { stateless, watch, onChange, options: usecaseOptions, ...restUseCaseOptions } = options;
|
|
5
|
+
return createEntityReducers(entity, usecase, {
|
|
6
|
+
...restUseCaseOptions,
|
|
7
|
+
...usecaseOptions,
|
|
8
|
+
onChange: onEntityChange,
|
|
9
|
+
onGenerate(newEntity, result) {
|
|
10
|
+
return result;
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const removeItem: <T>(list: T[], item: T) => void;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { OptionsRefCollection } from '../../hooks/useOptionsRefCollection/types';
|
|
2
|
+
import { UseCaseHookOptions } from '../../hooks/useUseCase/types';
|
|
3
|
+
export declare const triggerCallbacks: <T, TUseCaseOptions extends object, TOptions extends UseCaseHookOptions<T, TUseCaseOptions> = UseCaseHookOptions<T, TUseCaseOptions>>(optionsRefCollection: OptionsRefCollection<TOptions>, newEntity: T, prevEntity: T) => void;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { triggerWatchers } from '../triggerWatchers';
|
|
2
|
+
export const triggerCallbacks = (optionsRefCollection, newEntity, prevEntity) => {
|
|
3
|
+
for (let { length: i } = optionsRefCollection; i > 0; i--) {
|
|
4
|
+
const { current: options } = optionsRefCollection[i - 1];
|
|
5
|
+
if (!options) {
|
|
6
|
+
continue;
|
|
7
|
+
}
|
|
8
|
+
const { onChange, watch } = options;
|
|
9
|
+
if (watch) {
|
|
10
|
+
triggerWatchers(watch, newEntity, prevEntity);
|
|
11
|
+
}
|
|
12
|
+
onChange?.(newEntity, prevEntity);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { EntityWatchMap } from '../../types';
|
|
1
|
+
import { EntityWatchMap } from '../../hooks/useUseCase/types';
|
|
2
2
|
export declare const triggerWatchers: <T>(watch: EntityWatchMap<T>, newEntity: T, prevEntity: T) => void;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.UpdateFragment = void 0;
|
|
7
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
var UpdateFragment = function UpdateFragment(_ref) {
|
|
10
|
+
var onUpdate = _ref.onUpdate;
|
|
11
|
+
(0, _react.useEffect)(function () {
|
|
12
|
+
onUpdate === null || onUpdate === void 0 ? void 0 : onUpdate();
|
|
13
|
+
});
|
|
14
|
+
return (0, _jsxRuntime.jsx)(_react.Fragment, {});
|
|
15
|
+
};
|
|
16
|
+
exports.UpdateFragment = UpdateFragment;
|
|
@@ -5,5 +5,5 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.defaultUseCaseContext = void 0;
|
|
7
7
|
var _react = require("react");
|
|
8
|
-
var defaultUseCaseContext = (0, _react.createContext)(
|
|
8
|
+
var defaultUseCaseContext = (0, _react.createContext)({});
|
|
9
9
|
exports.defaultUseCaseContext = defaultUseCaseContext;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useCompareDeps = void 0;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _useScope = require("../useScope");
|
|
9
|
+
var useCompareDeps = function useCompareDeps(deps) {
|
|
10
|
+
var updateTimesRef = (0, _react.useRef)(0);
|
|
11
|
+
var prevDepsRef = (0, _react.useRef)([]);
|
|
12
|
+
var prevDeps = prevDepsRef.current;
|
|
13
|
+
var prevLength = prevDeps.length;
|
|
14
|
+
var length = deps.length;
|
|
15
|
+
var updated = (0, _useScope.useScope)(function () {
|
|
16
|
+
if (length !== prevLength) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
for (var i = 0; i < length; i++) {
|
|
20
|
+
if (deps[i] === prevDeps[i]) {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
return false;
|
|
26
|
+
});
|
|
27
|
+
prevDepsRef.current = deps;
|
|
28
|
+
updateTimesRef.current += updated ? 1 : 0;
|
|
29
|
+
return updateTimesRef.current;
|
|
30
|
+
};
|
|
31
|
+
exports.useCompareDeps = useCompareDeps;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.useConstant = void 0;
|
|
8
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
9
|
+
var _react = require("react");
|
|
10
|
+
var useConstant = function useConstant(initialValue) {
|
|
11
|
+
var _useState = (0, _react.useState)(initialValue),
|
|
12
|
+
_useState2 = (0, _slicedToArray2["default"])(_useState, 1),
|
|
13
|
+
value = _useState2[0];
|
|
14
|
+
return value;
|
|
15
|
+
};
|
|
16
|
+
exports.useConstant = useConstant;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.useConstantFn = void 0;
|
|
8
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
9
|
+
var _react = require("react");
|
|
10
|
+
var useConstantFn = function useConstantFn(initialValue) {
|
|
11
|
+
var _useState = (0, _react.useState)(function () {
|
|
12
|
+
return initialValue;
|
|
13
|
+
}),
|
|
14
|
+
_useState2 = (0, _slicedToArray2["default"])(_useState, 1),
|
|
15
|
+
value = _useState2[0];
|
|
16
|
+
return value;
|
|
17
|
+
};
|
|
18
|
+
exports.useConstantFn = useConstantFn;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useOptionsRefCollection = void 0;
|
|
7
|
+
var _ahooks = require("ahooks");
|
|
8
|
+
var _removeItem = require("../../methods/removeItem");
|
|
9
|
+
var useOptionsRefCollection = function useOptionsRefCollection(isRoot, contextOptionsRefCollection, options) {
|
|
10
|
+
var optionsRef = (0, _ahooks.useLatest)(options);
|
|
11
|
+
var optionsRefCollection = (0, _ahooks.useCreation)(function () {
|
|
12
|
+
if (isRoot) {
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
return contextOptionsRefCollection;
|
|
16
|
+
}, [contextOptionsRefCollection, isRoot]);
|
|
17
|
+
var prevOptionsRefCollection = (0, _ahooks.usePrevious)(optionsRefCollection);
|
|
18
|
+
(0, _ahooks.useCreation)(function () {
|
|
19
|
+
if (prevOptionsRefCollection) {
|
|
20
|
+
(0, _removeItem.removeItem)(prevOptionsRefCollection, optionsRef);
|
|
21
|
+
}
|
|
22
|
+
optionsRefCollection.push(optionsRef);
|
|
23
|
+
}, [optionsRef, optionsRefCollection, prevOptionsRefCollection]);
|
|
24
|
+
(0, _ahooks.useUnmount)(function () {
|
|
25
|
+
(0, _removeItem.removeItem)(optionsRefCollection, optionsRef);
|
|
26
|
+
});
|
|
27
|
+
return optionsRefCollection;
|
|
28
|
+
};
|
|
29
|
+
exports.useOptionsRefCollection = useOptionsRefCollection;
|