@mic-rexjs/usecases-react 1.3.35 → 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.
Files changed (85) hide show
  1. package/dist/index.min.js +1 -1
  2. package/es/components/UpdateFragment/index.d.ts +2 -0
  3. package/es/components/UpdateFragment/index.js +8 -0
  4. package/es/components/UpdateFragment/types.d.ts +3 -0
  5. package/es/components/UseCaseFragment/index.d.ts +1 -1
  6. package/es/components/UseCaseFragment/types.d.ts +2 -2
  7. package/es/configs/defaultUseCaseContext/index.d.ts +3 -1
  8. package/es/configs/defaultUseCaseContext/index.js +1 -1
  9. package/es/configs/defaultUseCaseContext/types.d.ts +11 -0
  10. package/es/configs/defaultUseCaseContext/types.js +1 -0
  11. package/es/configs/usecaseContextMap/index.d.ts +1 -3
  12. package/es/configs/usecaseContextMap/types.d.ts +4 -17
  13. package/es/hooks/useCompareDeps/index.d.ts +1 -0
  14. package/es/hooks/useCompareDeps/index.js +24 -0
  15. package/es/hooks/useConstant/index.d.ts +2 -0
  16. package/es/hooks/useConstant/index.js +5 -0
  17. package/es/hooks/useConstant/types.d.ts +3 -0
  18. package/es/hooks/useConstant/types.js +1 -0
  19. package/es/hooks/useConstantFn/index.d.ts +1 -0
  20. package/es/hooks/useConstantFn/index.js +7 -0
  21. package/es/hooks/useOptionsRefCollection/index.d.ts +3 -0
  22. package/es/hooks/useOptionsRefCollection/index.js +22 -0
  23. package/es/hooks/useOptionsRefCollection/types.d.ts +2 -0
  24. package/es/hooks/useOptionsRefCollection/types.js +1 -0
  25. package/es/hooks/useProvider/index.d.ts +7 -0
  26. package/es/hooks/useProvider/index.js +17 -0
  27. package/es/hooks/useProvider/types.d.ts +3 -0
  28. package/es/hooks/useProvider/types.js +1 -0
  29. package/es/hooks/useScope/index.d.ts +2 -0
  30. package/es/hooks/useScope/index.js +3 -0
  31. package/es/hooks/useScope/types.d.ts +3 -0
  32. package/es/hooks/useScope/types.js +1 -0
  33. package/es/hooks/useUseCase/index.js +68 -89
  34. package/es/hooks/useUseCase/index.test.js +166 -136
  35. package/es/hooks/useUseCase/types.d.ts +9 -7
  36. package/es/hooks/useUseCaseContext/index.d.ts +3 -0
  37. package/es/hooks/useUseCaseContext/index.js +17 -0
  38. package/es/index.d.ts +3 -2
  39. package/es/methods/getRootEntity/index.d.ts +2 -0
  40. package/es/methods/getRootEntity/index.js +9 -0
  41. package/es/methods/initEntityReducers/index.d.ts +5 -0
  42. package/es/methods/initEntityReducers/index.js +13 -0
  43. package/es/methods/initEntityReducers/types.d.ts +3 -0
  44. package/es/methods/initEntityReducers/types.js +1 -0
  45. package/es/methods/removeItem/index.d.ts +1 -0
  46. package/es/methods/removeItem/index.js +7 -0
  47. package/es/methods/triggerCallbacks/index.d.ts +3 -0
  48. package/es/methods/triggerCallbacks/index.js +14 -0
  49. package/es/{hooks/useUseCase/methods → methods}/triggerWatchers/index.d.ts +1 -1
  50. package/lib/components/UpdateFragment/index.js +16 -0
  51. package/lib/configs/defaultUseCaseContext/index.js +1 -1
  52. package/lib/configs/defaultUseCaseContext/types.js +5 -0
  53. package/lib/hooks/useCompareDeps/index.js +31 -0
  54. package/lib/hooks/useConstant/index.js +16 -0
  55. package/lib/hooks/useConstant/types.js +5 -0
  56. package/lib/hooks/useConstantFn/index.js +18 -0
  57. package/lib/hooks/useOptionsRefCollection/index.js +29 -0
  58. package/lib/hooks/useOptionsRefCollection/types.js +5 -0
  59. package/lib/hooks/useProvider/index.js +30 -0
  60. package/lib/hooks/useProvider/types.js +5 -0
  61. package/lib/hooks/useScope/index.js +10 -0
  62. package/lib/hooks/useScope/types.js +5 -0
  63. package/lib/hooks/useUseCase/index.js +73 -115
  64. package/lib/hooks/useUseCase/index.test.js +226 -177
  65. package/lib/hooks/useUseCaseContext/index.js +24 -0
  66. package/lib/methods/getRootEntity/index.js +16 -0
  67. package/lib/methods/initEntityReducers/index.js +29 -0
  68. package/lib/methods/initEntityReducers/types.js +5 -0
  69. package/lib/methods/removeItem/index.js +14 -0
  70. package/lib/methods/triggerCallbacks/index.js +22 -0
  71. package/package.json +2 -2
  72. package/es/core/usecases/optionsGetterCellectionUseCase/index.d.ts +0 -2
  73. package/es/core/usecases/optionsGetterCellectionUseCase/index.js +0 -13
  74. package/es/core/usecases/optionsGetterCellectionUseCase/types.d.ts +0 -8
  75. package/es/hooks/useOptionsTransfer/index.d.ts +0 -3
  76. package/es/hooks/useOptionsTransfer/index.js +0 -15
  77. package/es/hooks/useUseCase/methods/triggerCallbacks/index.d.ts +0 -3
  78. package/es/hooks/useUseCase/methods/triggerCallbacks/index.js +0 -11
  79. package/lib/core/usecases/optionsGetterCellectionUseCase/index.js +0 -23
  80. package/lib/hooks/useOptionsTransfer/index.js +0 -23
  81. package/lib/hooks/useUseCase/methods/triggerCallbacks/index.js +0 -32
  82. /package/es/{core/usecases/optionsGetterCellectionUseCase → components/UpdateFragment}/types.js +0 -0
  83. /package/es/{hooks/useUseCase/methods → methods}/triggerWatchers/index.js +0 -0
  84. /package/lib/{core/usecases/optionsGetterCellectionUseCase → components/UpdateFragment}/types.js +0 -0
  85. /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+ argument on accessor mode', () => {
418
- test('check `context.length`', () => {
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(fileUseCase);
421
+ return useUseCase(mathUseCase);
421
422
  });
422
- const { current: context } = result;
423
- expect(context).toHaveLength(2);
423
+ const { current: reducers } = result;
424
+ expect(Array.isArray(reducers)).toBe(false);
424
425
  });
425
- test('`entity` should be `undefined`', () => {
426
+ test('returned reducer should work', () => {
426
427
  const { result } = renderHook(() => {
427
- return useUseCase(fileUseCase);
428
+ return useUseCase(mathUseCase);
428
429
  });
429
- const { current: context } = result;
430
- const [entity] = context;
431
- expect(entity).toBe(void 0);
430
+ const { current: reducers } = result;
431
+ const { add } = reducers;
432
+ expect(add(1, 2)).toBe(3);
432
433
  });
433
- test('`reducers` should be returned as an object', () => {
434
+ test('`options.extraValue` should be added after call `add` method', () => {
434
435
  const { result } = renderHook(() => {
435
- return useUseCase(fileUseCase);
436
+ return useUseCase(mathUseCase, { extraValue: 5 });
436
437
  });
437
- const { current: context } = result;
438
- const [, reducers] = context;
439
- expect(typeof reducers).toBe('object');
438
+ const { current: reducers } = result;
439
+ const { add } = reducers;
440
+ expect(add(1, 2)).toBe(8);
440
441
  });
441
- test('`yield entity` should not trigger update', () => {
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
- return useUseCase(fileUseCase);
450
+ }, [reducers]);
451
+ useDeepCompareUpdate(() => {
452
+ onDeepUpdate();
453
+ }, [reducers]);
454
+ return setExtraValue;
448
455
  });
449
- const { current: context } = result;
450
- const [, reducers] = context;
451
- const { setPath } = reducers;
456
+ expect(onUpdate).toHaveBeenCalledTimes(0);
457
+ expect(onDeepUpdate).toHaveBeenCalledTimes(0);
452
458
  act(() => {
453
- setPath(PATH_1);
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('should work within <Child />', () => {
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 onUpdate1 = jest.fn();
462
- const onPathChange1 = jest.fn();
463
- const onUndefinedEntity1 = jest.fn();
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(_jsxs("div", { children: [_jsx(Parent, { onSetPath: onSetPath, children: _jsx(Child, { textPrefix: textPrefix, onUpdate: onUpdate1, onPathChange: onPathChange1, onUndefinedEntity: onUndefinedEntity1 }) }), _jsx(Child, { onUpdate: onUpdate2, onPathChange: onPathChange2, onUndefinedEntity: onUndefinedEntity2 })] }));
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(onUpdate1).toHaveBeenCalledTimes(1);
474
- expect(onPathChange1).toHaveBeenCalledWith(PATH_1);
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(onUpdate1).toHaveBeenCalledTimes(2);
478
- expect(onPathChange1).toHaveBeenCalledWith('');
479
- expect(onUpdate2).toHaveBeenCalledTimes(0);
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
- describe('`useUseCase` should work with 1+ arguments on non-entity mode', () => {
574
- test('`entity` should equal `defaultFile`', () => {
575
- const { result } = renderHook(() => {
576
- return useUseCase(mathUseCase);
577
- });
578
- const { current: reducers } = result;
579
- expect(typeof reducers).toBe('object');
580
- });
581
- test('returned reducer should work', () => {
582
- const { result } = renderHook(() => {
583
- return useUseCase(mathUseCase);
584
- });
585
- const { current: reducers } = result;
586
- const { add } = reducers;
587
- expect(add(1, 2)).toBe(3);
588
- });
589
- test('`options.extraValue` should be added after call `add` method', () => {
590
- const { result } = renderHook(() => {
591
- return useUseCase(mathUseCase, { extraValue: 5 });
592
- });
593
- const { current: reducers } = result;
594
- const { add } = reducers;
595
- expect(add(1, 2)).toBe(8);
596
- });
597
- test('when `options` has changed, it should not trigger update', () => {
598
- const onUpdate = jest.fn();
599
- const onDeepUpdate = jest.fn();
600
- const { result } = renderHook(() => {
601
- const [extraValue, setExtraValue] = useState(0);
602
- const reducers = useUseCase(mathUseCase, { extraValue });
603
- useUpdateEffect(() => {
604
- onUpdate();
605
- }, [reducers]);
606
- useDeepCompareUpdate(() => {
607
- onDeepUpdate();
608
- }, [reducers]);
609
- return setExtraValue;
610
- });
611
- expect(onUpdate).toHaveBeenCalledTimes(0);
612
- expect(onDeepUpdate).toHaveBeenCalledTimes(0);
613
- act(() => {
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 { UseCaseContext, UseCaseContextWithProvider } from '../../configs/usecaseContextMap/types';
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, TOptions extends object> extends UseCaseHookContextualOptions<T> {
18
+ export interface UseCaseHookOwnOptions<T, TUseCaseOptions extends object> extends UseCaseHookContextualOptions<T> {
17
19
  stateless?: boolean;
18
- options?: TOptions;
20
+ options?: TUseCaseOptions;
19
21
  }
20
- export type UseCaseHookOptions<T, TOptions extends object> = TOptions & UseCaseHookOwnOptions<T, TOptions>;
22
+ export type UseCaseHookOptions<T, TUseCaseOptions extends object = object> = TUseCaseOptions & UseCaseHookOwnOptions<T, TUseCaseOptions>;
21
23
  export interface UseCaseHook {
22
- <T, TReducers extends EntityReducers<T>, TOptions extends UseCaseHookContextualOptions<T> = UseCaseHookContextualOptions<T>>(usecase: EntityUseCase<T, TReducers & EntityReducers<T>>, options?: TOptions): UseCaseContext<T, TReducers>;
23
- <T, TReducers extends EntityReducers<T>, TUseCaseOptions extends object = object, TOptions extends UseCaseHookOptions<T, TUseCaseOptions> = UseCaseHookOptions<T, TUseCaseOptions>>(defaultEntity: T | EntityGetter<T>, usecase: EntityUseCase<T, TReducers, TUseCaseOptions> & UseCase<TReducers, TUseCaseOptions>, options?: TOptions, deps?: unknown[]): UseCaseContextWithProvider<T, TReducers>;
24
- <T extends Reducers, TOptions extends object = object>(usecase: UseCase<T, TOptions>, options?: TOptions, deps?: unknown[]): T;
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 { UseCaseFragmentProps } from './components/UseCaseFragment/types';
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,2 @@
1
+ import { EntityGetter } from '../../hooks/useUseCase/types';
2
+ export declare const getRootEntity: <T>(entityState: T, entityArg: T | EntityGetter<T>, stateless?: boolean) => T;
@@ -0,0 +1,9 @@
1
+ export const getRootEntity = (entityState, entityArg, stateless) => {
2
+ if (!stateless) {
3
+ return entityState;
4
+ }
5
+ if (typeof entityArg === 'function') {
6
+ return entityArg();
7
+ }
8
+ return entityArg;
9
+ };
@@ -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,3 @@
1
+ export interface EntityChangeEventHandler<T> {
2
+ (newEntity: T, prevEntity: T): void;
3
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export declare const removeItem: <T>(list: T[], item: T) => void;
@@ -0,0 +1,7 @@
1
+ export const removeItem = (list, item) => {
2
+ const index = list.indexOf(item);
3
+ if (index === -1) {
4
+ return;
5
+ }
6
+ list.splice(index, 1);
7
+ };
@@ -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)(null);
8
+ var defaultUseCaseContext = (0, _react.createContext)({});
9
9
  exports.defaultUseCaseContext = defaultUseCaseContext;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
@@ -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,5 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
@@ -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;