@wordpress/data 6.3.0 → 6.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/CHANGELOG.md +4 -0
- package/build/components/use-select/index.js +1 -1
- package/build/components/use-select/index.js.map +1 -1
- package/build/factory.js +1 -1
- package/build/factory.js.map +1 -1
- package/build/plugins/persistence/index.js +114 -12
- package/build/plugins/persistence/index.js.map +1 -1
- package/build/redux-store/index.js +24 -8
- package/build/redux-store/index.js.map +1 -1
- package/build/redux-store/metadata/actions.js +47 -4
- package/build/redux-store/metadata/actions.js.map +1 -1
- package/build/redux-store/metadata/reducer.js +57 -4
- package/build/redux-store/metadata/reducer.js.map +1 -1
- package/build/redux-store/metadata/selectors.js +71 -7
- package/build/redux-store/metadata/selectors.js.map +1 -1
- package/build/registry.js +0 -2
- package/build/registry.js.map +1 -1
- package/build/resolvers-cache-middleware.js +3 -3
- package/build/resolvers-cache-middleware.js.map +1 -1
- package/build-module/components/use-select/index.js +1 -1
- package/build-module/components/use-select/index.js.map +1 -1
- package/build-module/factory.js +1 -1
- package/build-module/factory.js.map +1 -1
- package/build-module/plugins/persistence/index.js +111 -12
- package/build-module/plugins/persistence/index.js.map +1 -1
- package/build-module/redux-store/index.js +24 -8
- package/build-module/redux-store/index.js.map +1 -1
- package/build-module/redux-store/metadata/actions.js +43 -4
- package/build-module/redux-store/metadata/actions.js.map +1 -1
- package/build-module/redux-store/metadata/reducer.js +57 -4
- package/build-module/redux-store/metadata/reducer.js.map +1 -1
- package/build-module/redux-store/metadata/selectors.js +65 -7
- package/build-module/redux-store/metadata/selectors.js.map +1 -1
- package/build-module/registry.js +0 -2
- package/build-module/registry.js.map +1 -1
- package/build-module/resolvers-cache-middleware.js +3 -3
- package/build-module/resolvers-cache-middleware.js.map +1 -1
- package/build-types/redux-store/metadata/actions.d.ts +37 -4
- package/build-types/redux-store/metadata/actions.d.ts.map +1 -1
- package/build-types/redux-store/metadata/reducer.d.ts +10 -2
- package/build-types/redux-store/metadata/reducer.d.ts.map +1 -1
- package/build-types/redux-store/metadata/selectors.d.ts +40 -0
- package/build-types/redux-store/metadata/selectors.d.ts.map +1 -1
- package/build-types/types.d.ts.map +1 -1
- package/package.json +8 -8
- package/src/components/use-select/index.js +1 -1
- package/src/components/use-select/test/index.js +7 -7
- package/src/components/with-select/test/index.js +3 -3
- package/src/factory.js +1 -1
- package/src/plugins/persistence/index.js +142 -8
- package/src/plugins/persistence/test/index.js +405 -0
- package/src/redux-store/index.js +43 -15
- package/src/redux-store/metadata/actions.js +43 -4
- package/src/redux-store/metadata/reducer.ts +60 -9
- package/src/redux-store/metadata/selectors.js +60 -7
- package/src/redux-store/metadata/test/reducer.js +64 -24
- package/src/redux-store/metadata/test/selectors.js +263 -53
- package/src/redux-store/test/index.js +42 -0
- package/src/registry.js +0 -2
- package/src/resolvers-cache-middleware.js +4 -3
- package/src/test/controls.js +7 -7
- package/src/test/registry.js +6 -6
- package/src/types.ts +1 -3
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -10,6 +10,8 @@ import plugin, {
|
|
|
10
10
|
createPersistenceInterface,
|
|
11
11
|
withLazySameState,
|
|
12
12
|
migrateFeaturePreferencesToInterfaceStore,
|
|
13
|
+
migrateFeaturePreferencesToPreferencesStore,
|
|
14
|
+
migrateIndividualPreferenceToPreferencesStore,
|
|
13
15
|
} from '../';
|
|
14
16
|
import objectStorage from '../storage/object';
|
|
15
17
|
import { createRegistry } from '../../../';
|
|
@@ -492,4 +494,407 @@ describe( 'migrateFeaturePreferencesToInterfaceStore', () => {
|
|
|
492
494
|
},
|
|
493
495
|
} );
|
|
494
496
|
} );
|
|
497
|
+
|
|
498
|
+
describe( 'migrateFeaturePreferencesToPreferencesStore', () => {
|
|
499
|
+
it( 'migrates multiple preferences from persisted source stores to preferences', () => {
|
|
500
|
+
const persistenceInterface = createPersistenceInterface( {
|
|
501
|
+
storageKey: 'test-username',
|
|
502
|
+
} );
|
|
503
|
+
|
|
504
|
+
const sourceStateA = {
|
|
505
|
+
preferences: {
|
|
506
|
+
features: {
|
|
507
|
+
featureA: true,
|
|
508
|
+
featureB: false,
|
|
509
|
+
featureC: true,
|
|
510
|
+
},
|
|
511
|
+
},
|
|
512
|
+
};
|
|
513
|
+
|
|
514
|
+
const sourceStateB = {
|
|
515
|
+
preferences: {
|
|
516
|
+
features: {
|
|
517
|
+
featureD: true,
|
|
518
|
+
featureE: false,
|
|
519
|
+
featureF: true,
|
|
520
|
+
},
|
|
521
|
+
},
|
|
522
|
+
};
|
|
523
|
+
|
|
524
|
+
persistenceInterface.set( 'core/test-a', sourceStateA );
|
|
525
|
+
persistenceInterface.set( 'core/test-b', sourceStateB );
|
|
526
|
+
|
|
527
|
+
migrateFeaturePreferencesToPreferencesStore(
|
|
528
|
+
persistenceInterface,
|
|
529
|
+
'core/test-a'
|
|
530
|
+
);
|
|
531
|
+
|
|
532
|
+
migrateFeaturePreferencesToPreferencesStore(
|
|
533
|
+
persistenceInterface,
|
|
534
|
+
'core/test-b'
|
|
535
|
+
);
|
|
536
|
+
|
|
537
|
+
expect( persistenceInterface.get() ).toEqual( {
|
|
538
|
+
'core/preferences': {
|
|
539
|
+
preferences: {
|
|
540
|
+
'core/test-a': {
|
|
541
|
+
featureA: true,
|
|
542
|
+
featureB: false,
|
|
543
|
+
featureC: true,
|
|
544
|
+
},
|
|
545
|
+
'core/test-b': {
|
|
546
|
+
featureD: true,
|
|
547
|
+
featureE: false,
|
|
548
|
+
featureF: true,
|
|
549
|
+
},
|
|
550
|
+
},
|
|
551
|
+
},
|
|
552
|
+
'core/test-a': {
|
|
553
|
+
preferences: {
|
|
554
|
+
features: undefined,
|
|
555
|
+
},
|
|
556
|
+
},
|
|
557
|
+
'core/test-b': {
|
|
558
|
+
preferences: {
|
|
559
|
+
features: undefined,
|
|
560
|
+
},
|
|
561
|
+
},
|
|
562
|
+
} );
|
|
563
|
+
} );
|
|
564
|
+
|
|
565
|
+
it( 'migrates multiple preferences from the persisted interface store to preferences, with interface state taking precedence over source stores', () => {
|
|
566
|
+
const persistenceInterface = createPersistenceInterface( {
|
|
567
|
+
storageKey: 'test-username',
|
|
568
|
+
} );
|
|
569
|
+
|
|
570
|
+
const sourceStateA = {
|
|
571
|
+
preferences: {
|
|
572
|
+
features: {
|
|
573
|
+
featureA: true,
|
|
574
|
+
featureB: false,
|
|
575
|
+
featureC: true,
|
|
576
|
+
},
|
|
577
|
+
},
|
|
578
|
+
};
|
|
579
|
+
|
|
580
|
+
const sourceStateB = {
|
|
581
|
+
preferences: {
|
|
582
|
+
features: {
|
|
583
|
+
featureD: true,
|
|
584
|
+
featureE: false,
|
|
585
|
+
featureF: true,
|
|
586
|
+
},
|
|
587
|
+
},
|
|
588
|
+
};
|
|
589
|
+
|
|
590
|
+
const interfaceState = {
|
|
591
|
+
preferences: {
|
|
592
|
+
features: {
|
|
593
|
+
'core/test-a': {
|
|
594
|
+
featureG: true,
|
|
595
|
+
featureH: false,
|
|
596
|
+
featureI: true,
|
|
597
|
+
},
|
|
598
|
+
'core/test-b': {
|
|
599
|
+
featureJ: true,
|
|
600
|
+
featureK: false,
|
|
601
|
+
featureL: true,
|
|
602
|
+
},
|
|
603
|
+
},
|
|
604
|
+
},
|
|
605
|
+
};
|
|
606
|
+
|
|
607
|
+
persistenceInterface.set( 'core/test-a', sourceStateA );
|
|
608
|
+
persistenceInterface.set( 'core/test-b', sourceStateB );
|
|
609
|
+
persistenceInterface.set( 'core/interface', interfaceState );
|
|
610
|
+
|
|
611
|
+
migrateFeaturePreferencesToPreferencesStore(
|
|
612
|
+
persistenceInterface,
|
|
613
|
+
'core/test-a'
|
|
614
|
+
);
|
|
615
|
+
|
|
616
|
+
migrateFeaturePreferencesToPreferencesStore(
|
|
617
|
+
persistenceInterface,
|
|
618
|
+
'core/test-b'
|
|
619
|
+
);
|
|
620
|
+
|
|
621
|
+
expect( persistenceInterface.get() ).toEqual( {
|
|
622
|
+
'core/preferences': {
|
|
623
|
+
preferences: {
|
|
624
|
+
'core/test-a': {
|
|
625
|
+
featureG: true,
|
|
626
|
+
featureH: false,
|
|
627
|
+
featureI: true,
|
|
628
|
+
},
|
|
629
|
+
'core/test-b': {
|
|
630
|
+
featureJ: true,
|
|
631
|
+
featureK: false,
|
|
632
|
+
featureL: true,
|
|
633
|
+
},
|
|
634
|
+
},
|
|
635
|
+
},
|
|
636
|
+
'core/interface': {
|
|
637
|
+
preferences: {
|
|
638
|
+
features: {
|
|
639
|
+
'core/test-a': undefined,
|
|
640
|
+
'core/test-b': undefined,
|
|
641
|
+
},
|
|
642
|
+
},
|
|
643
|
+
},
|
|
644
|
+
'core/test-a': {
|
|
645
|
+
preferences: {
|
|
646
|
+
features: undefined,
|
|
647
|
+
},
|
|
648
|
+
},
|
|
649
|
+
'core/test-b': {
|
|
650
|
+
preferences: {
|
|
651
|
+
features: undefined,
|
|
652
|
+
},
|
|
653
|
+
},
|
|
654
|
+
} );
|
|
655
|
+
} );
|
|
656
|
+
|
|
657
|
+
it( 'only migrates persisted data for the source name from source stores', () => {
|
|
658
|
+
const persistenceInterface = createPersistenceInterface( {
|
|
659
|
+
storageKey: 'test-username',
|
|
660
|
+
} );
|
|
661
|
+
|
|
662
|
+
const sourceStateA = {
|
|
663
|
+
preferences: {
|
|
664
|
+
features: {
|
|
665
|
+
featureA: true,
|
|
666
|
+
featureB: false,
|
|
667
|
+
featureC: true,
|
|
668
|
+
},
|
|
669
|
+
},
|
|
670
|
+
};
|
|
671
|
+
|
|
672
|
+
const sourceStateB = {
|
|
673
|
+
preferences: {
|
|
674
|
+
features: {
|
|
675
|
+
featureD: true,
|
|
676
|
+
featureE: false,
|
|
677
|
+
featureF: true,
|
|
678
|
+
},
|
|
679
|
+
},
|
|
680
|
+
};
|
|
681
|
+
|
|
682
|
+
persistenceInterface.set( 'core/test-a', sourceStateA );
|
|
683
|
+
persistenceInterface.set( 'core/test-b', sourceStateB );
|
|
684
|
+
|
|
685
|
+
migrateFeaturePreferencesToPreferencesStore(
|
|
686
|
+
persistenceInterface,
|
|
687
|
+
'core/test-a'
|
|
688
|
+
);
|
|
689
|
+
|
|
690
|
+
expect( persistenceInterface.get() ).toEqual( {
|
|
691
|
+
'core/preferences': {
|
|
692
|
+
preferences: {
|
|
693
|
+
'core/test-a': {
|
|
694
|
+
featureA: true,
|
|
695
|
+
featureB: false,
|
|
696
|
+
featureC: true,
|
|
697
|
+
},
|
|
698
|
+
},
|
|
699
|
+
},
|
|
700
|
+
'core/test-a': {
|
|
701
|
+
preferences: {
|
|
702
|
+
features: undefined,
|
|
703
|
+
},
|
|
704
|
+
},
|
|
705
|
+
'core/test-b': {
|
|
706
|
+
preferences: {
|
|
707
|
+
features: {
|
|
708
|
+
featureD: true,
|
|
709
|
+
featureE: false,
|
|
710
|
+
featureF: true,
|
|
711
|
+
},
|
|
712
|
+
},
|
|
713
|
+
},
|
|
714
|
+
} );
|
|
715
|
+
} );
|
|
716
|
+
|
|
717
|
+
it( 'only migrates persisted data for the source name from interface', () => {
|
|
718
|
+
const persistenceInterface = createPersistenceInterface( {
|
|
719
|
+
storageKey: 'test-username',
|
|
720
|
+
} );
|
|
721
|
+
|
|
722
|
+
const interfaceState = {
|
|
723
|
+
preferences: {
|
|
724
|
+
features: {
|
|
725
|
+
'core/test-a': {
|
|
726
|
+
featureG: true,
|
|
727
|
+
featureH: false,
|
|
728
|
+
featureI: true,
|
|
729
|
+
},
|
|
730
|
+
'core/test-b': {
|
|
731
|
+
featureJ: true,
|
|
732
|
+
featureK: false,
|
|
733
|
+
featureL: true,
|
|
734
|
+
},
|
|
735
|
+
},
|
|
736
|
+
},
|
|
737
|
+
};
|
|
738
|
+
|
|
739
|
+
persistenceInterface.set( 'core/interface', interfaceState );
|
|
740
|
+
|
|
741
|
+
migrateFeaturePreferencesToPreferencesStore(
|
|
742
|
+
persistenceInterface,
|
|
743
|
+
'core/test-a'
|
|
744
|
+
);
|
|
745
|
+
|
|
746
|
+
expect( persistenceInterface.get() ).toEqual( {
|
|
747
|
+
'core/preferences': {
|
|
748
|
+
preferences: {
|
|
749
|
+
'core/test-a': {
|
|
750
|
+
featureG: true,
|
|
751
|
+
featureH: false,
|
|
752
|
+
featureI: true,
|
|
753
|
+
},
|
|
754
|
+
},
|
|
755
|
+
},
|
|
756
|
+
'core/interface': {
|
|
757
|
+
preferences: {
|
|
758
|
+
features: {
|
|
759
|
+
'core/test-a': undefined,
|
|
760
|
+
'core/test-b': {
|
|
761
|
+
featureJ: true,
|
|
762
|
+
featureK: false,
|
|
763
|
+
featureL: true,
|
|
764
|
+
},
|
|
765
|
+
},
|
|
766
|
+
},
|
|
767
|
+
},
|
|
768
|
+
} );
|
|
769
|
+
} );
|
|
770
|
+
} );
|
|
771
|
+
|
|
772
|
+
describe( 'migrateIndividualPreferenceToPreferencesStore', () => {
|
|
773
|
+
it( 'migrates an individual preference from the source to the preferences store', () => {
|
|
774
|
+
const persistenceInterface = createPersistenceInterface( {
|
|
775
|
+
storageKey: 'test-username',
|
|
776
|
+
} );
|
|
777
|
+
|
|
778
|
+
const initialState = {
|
|
779
|
+
preferences: {
|
|
780
|
+
myPreference: '123',
|
|
781
|
+
},
|
|
782
|
+
};
|
|
783
|
+
|
|
784
|
+
persistenceInterface.set( 'core/test', initialState );
|
|
785
|
+
|
|
786
|
+
migrateIndividualPreferenceToPreferencesStore(
|
|
787
|
+
persistenceInterface,
|
|
788
|
+
'core/test',
|
|
789
|
+
'myPreference'
|
|
790
|
+
);
|
|
791
|
+
|
|
792
|
+
expect( persistenceInterface.get() ).toEqual( {
|
|
793
|
+
'core/preferences': {
|
|
794
|
+
preferences: {
|
|
795
|
+
'core/test': {
|
|
796
|
+
myPreference: '123',
|
|
797
|
+
},
|
|
798
|
+
},
|
|
799
|
+
},
|
|
800
|
+
'core/test': {
|
|
801
|
+
preferences: {
|
|
802
|
+
myPreference: undefined,
|
|
803
|
+
},
|
|
804
|
+
},
|
|
805
|
+
} );
|
|
806
|
+
} );
|
|
807
|
+
|
|
808
|
+
it( 'does not overwrite other preferences in the preferences store', () => {
|
|
809
|
+
const persistenceInterface = createPersistenceInterface( {
|
|
810
|
+
storageKey: 'test-username',
|
|
811
|
+
} );
|
|
812
|
+
|
|
813
|
+
const initialState = {
|
|
814
|
+
preferences: {
|
|
815
|
+
myPreference: '123',
|
|
816
|
+
},
|
|
817
|
+
};
|
|
818
|
+
|
|
819
|
+
persistenceInterface.set( 'core/test', initialState );
|
|
820
|
+
persistenceInterface.set( 'core/preferences', {
|
|
821
|
+
preferences: {
|
|
822
|
+
'core/other-store': {
|
|
823
|
+
preferenceA: 1,
|
|
824
|
+
preferenceB: 2,
|
|
825
|
+
},
|
|
826
|
+
'core/test': {
|
|
827
|
+
unrelatedPreference: 'unrelated-value',
|
|
828
|
+
},
|
|
829
|
+
},
|
|
830
|
+
} );
|
|
831
|
+
|
|
832
|
+
migrateIndividualPreferenceToPreferencesStore(
|
|
833
|
+
persistenceInterface,
|
|
834
|
+
'core/test',
|
|
835
|
+
'myPreference'
|
|
836
|
+
);
|
|
837
|
+
|
|
838
|
+
expect( persistenceInterface.get() ).toEqual( {
|
|
839
|
+
'core/preferences': {
|
|
840
|
+
preferences: {
|
|
841
|
+
'core/other-store': {
|
|
842
|
+
preferenceA: 1,
|
|
843
|
+
preferenceB: 2,
|
|
844
|
+
},
|
|
845
|
+
'core/test': {
|
|
846
|
+
unrelatedPreference: 'unrelated-value',
|
|
847
|
+
myPreference: '123',
|
|
848
|
+
},
|
|
849
|
+
},
|
|
850
|
+
},
|
|
851
|
+
'core/test': {
|
|
852
|
+
preferences: {
|
|
853
|
+
myPreference: undefined,
|
|
854
|
+
},
|
|
855
|
+
},
|
|
856
|
+
} );
|
|
857
|
+
} );
|
|
858
|
+
|
|
859
|
+
it( 'does not migrate data if there is already a matching preference key at the target', () => {
|
|
860
|
+
const persistenceInterface = createPersistenceInterface( {
|
|
861
|
+
storageKey: 'test-username',
|
|
862
|
+
} );
|
|
863
|
+
|
|
864
|
+
persistenceInterface.set( 'core/test', {
|
|
865
|
+
preferences: {
|
|
866
|
+
myPreference: '123',
|
|
867
|
+
},
|
|
868
|
+
} );
|
|
869
|
+
|
|
870
|
+
persistenceInterface.set( 'core/preferences', {
|
|
871
|
+
preferences: {
|
|
872
|
+
'core/test': {
|
|
873
|
+
myPreference: 'already-set',
|
|
874
|
+
},
|
|
875
|
+
},
|
|
876
|
+
} );
|
|
877
|
+
|
|
878
|
+
migrateIndividualPreferenceToPreferencesStore(
|
|
879
|
+
persistenceInterface,
|
|
880
|
+
'core/test',
|
|
881
|
+
'myPreference'
|
|
882
|
+
);
|
|
883
|
+
|
|
884
|
+
expect( persistenceInterface.get() ).toEqual( {
|
|
885
|
+
'core/preferences': {
|
|
886
|
+
preferences: {
|
|
887
|
+
'core/test': {
|
|
888
|
+
myPreference: 'already-set',
|
|
889
|
+
},
|
|
890
|
+
},
|
|
891
|
+
},
|
|
892
|
+
'core/test': {
|
|
893
|
+
preferences: {
|
|
894
|
+
myPreference: '123',
|
|
895
|
+
},
|
|
896
|
+
},
|
|
897
|
+
} );
|
|
898
|
+
} );
|
|
899
|
+
} );
|
|
495
900
|
} );
|
package/src/redux-store/index.js
CHANGED
|
@@ -330,20 +330,35 @@ function mapResolveSelectors( selectors, store ) {
|
|
|
330
330
|
'getCachedResolvers',
|
|
331
331
|
] ),
|
|
332
332
|
( selector, selectorName ) => ( ...args ) =>
|
|
333
|
-
new Promise( ( resolve ) => {
|
|
333
|
+
new Promise( ( resolve, reject ) => {
|
|
334
334
|
const hasFinished = () =>
|
|
335
335
|
selectors.hasFinishedResolution( selectorName, args );
|
|
336
|
+
const finalize = ( result ) => {
|
|
337
|
+
const hasFailed = selectors.hasResolutionFailed(
|
|
338
|
+
selectorName,
|
|
339
|
+
args
|
|
340
|
+
);
|
|
341
|
+
if ( hasFailed ) {
|
|
342
|
+
const error = selectors.getResolutionError(
|
|
343
|
+
selectorName,
|
|
344
|
+
args
|
|
345
|
+
);
|
|
346
|
+
reject( error );
|
|
347
|
+
} else {
|
|
348
|
+
resolve( result );
|
|
349
|
+
}
|
|
350
|
+
};
|
|
336
351
|
const getResult = () => selector.apply( null, args );
|
|
337
|
-
//
|
|
352
|
+
// Trigger the selector (to trigger the resolver)
|
|
338
353
|
const result = getResult();
|
|
339
354
|
if ( hasFinished() ) {
|
|
340
|
-
return
|
|
355
|
+
return finalize( result );
|
|
341
356
|
}
|
|
342
357
|
|
|
343
358
|
const unsubscribe = store.subscribe( () => {
|
|
344
359
|
if ( hasFinished() ) {
|
|
345
360
|
unsubscribe();
|
|
346
|
-
|
|
361
|
+
finalize( getResult() );
|
|
347
362
|
}
|
|
348
363
|
} );
|
|
349
364
|
} )
|
|
@@ -370,8 +385,8 @@ function mapResolvers( resolvers, selectors, store, resolversCache ) {
|
|
|
370
385
|
}
|
|
371
386
|
|
|
372
387
|
return {
|
|
373
|
-
...resolver, //
|
|
374
|
-
fulfill: resolver, //
|
|
388
|
+
...resolver, // Copy the enumerable properties of the resolver function.
|
|
389
|
+
fulfill: resolver, // Add the fulfill method.
|
|
375
390
|
};
|
|
376
391
|
} );
|
|
377
392
|
|
|
@@ -413,15 +428,28 @@ function mapResolvers( resolvers, selectors, store, resolversCache ) {
|
|
|
413
428
|
store.dispatch(
|
|
414
429
|
metadataActions.startResolution( selectorName, args )
|
|
415
430
|
);
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
431
|
+
try {
|
|
432
|
+
await fulfillResolver(
|
|
433
|
+
store,
|
|
434
|
+
mappedResolvers,
|
|
435
|
+
selectorName,
|
|
436
|
+
...args
|
|
437
|
+
);
|
|
438
|
+
store.dispatch(
|
|
439
|
+
metadataActions.finishResolution(
|
|
440
|
+
selectorName,
|
|
441
|
+
args
|
|
442
|
+
)
|
|
443
|
+
);
|
|
444
|
+
} catch ( error ) {
|
|
445
|
+
store.dispatch(
|
|
446
|
+
metadataActions.failResolution(
|
|
447
|
+
selectorName,
|
|
448
|
+
args,
|
|
449
|
+
error
|
|
450
|
+
)
|
|
451
|
+
);
|
|
452
|
+
}
|
|
425
453
|
} );
|
|
426
454
|
}
|
|
427
455
|
|
|
@@ -32,13 +32,32 @@ export function finishResolution( selectorName, args ) {
|
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Returns an action object used in signalling that selector resolution has
|
|
37
|
+
* failed.
|
|
38
|
+
*
|
|
39
|
+
* @param {string} selectorName Name of selector for which resolver triggered.
|
|
40
|
+
* @param {unknown[]} args Arguments to associate for uniqueness.
|
|
41
|
+
* @param {Error|unknown} error The error that caused the failure.
|
|
42
|
+
*
|
|
43
|
+
* @return {{ type: 'FAIL_RESOLUTION', selectorName: string, args: unknown[], error: Error|unknown }} Action object.
|
|
44
|
+
*/
|
|
45
|
+
export function failResolution( selectorName, args, error ) {
|
|
46
|
+
return {
|
|
47
|
+
type: 'FAIL_RESOLUTION',
|
|
48
|
+
selectorName,
|
|
49
|
+
args,
|
|
50
|
+
error,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
35
54
|
/**
|
|
36
55
|
* Returns an action object used in signalling that a batch of selector resolutions has
|
|
37
56
|
* started.
|
|
38
57
|
*
|
|
39
|
-
* @param {string}
|
|
58
|
+
* @param {string} selectorName Name of selector for which resolver triggered.
|
|
40
59
|
* @param {unknown[][]} args Array of arguments to associate for uniqueness, each item
|
|
41
|
-
*
|
|
60
|
+
* is associated to a resolution.
|
|
42
61
|
*
|
|
43
62
|
* @return {{ type: 'START_RESOLUTIONS', selectorName: string, args: unknown[][] }} Action object.
|
|
44
63
|
*/
|
|
@@ -54,9 +73,9 @@ export function startResolutions( selectorName, args ) {
|
|
|
54
73
|
* Returns an action object used in signalling that a batch of selector resolutions has
|
|
55
74
|
* completed.
|
|
56
75
|
*
|
|
57
|
-
* @param {string}
|
|
76
|
+
* @param {string} selectorName Name of selector for which resolver triggered.
|
|
58
77
|
* @param {unknown[][]} args Array of arguments to associate for uniqueness, each item
|
|
59
|
-
*
|
|
78
|
+
* is associated to a resolution.
|
|
60
79
|
*
|
|
61
80
|
* @return {{ type: 'FINISH_RESOLUTIONS', selectorName: string, args: unknown[][] }} Action object.
|
|
62
81
|
*/
|
|
@@ -68,6 +87,26 @@ export function finishResolutions( selectorName, args ) {
|
|
|
68
87
|
};
|
|
69
88
|
}
|
|
70
89
|
|
|
90
|
+
/**
|
|
91
|
+
* Returns an action object used in signalling that a batch of selector resolutions has
|
|
92
|
+
* completed and at least one of them has failed.
|
|
93
|
+
*
|
|
94
|
+
* @param {string} selectorName Name of selector for which resolver triggered.
|
|
95
|
+
* @param {unknown[]} args Array of arguments to associate for uniqueness, each item
|
|
96
|
+
* is associated to a resolution.
|
|
97
|
+
* @param {(Error|unknown)[]} errors Array of errors to associate for uniqueness, each item
|
|
98
|
+
* is associated to a resolution.
|
|
99
|
+
* @return {{ type: 'FAIL_RESOLUTIONS', selectorName: string, args: unknown[], errors: Array<Error|unknown> }} Action object.
|
|
100
|
+
*/
|
|
101
|
+
export function failResolutions( selectorName, args, errors ) {
|
|
102
|
+
return {
|
|
103
|
+
type: 'FAIL_RESOLUTIONS',
|
|
104
|
+
selectorName,
|
|
105
|
+
args,
|
|
106
|
+
errors,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
71
110
|
/**
|
|
72
111
|
* Returns an action object used in signalling that we should invalidate the resolution cache.
|
|
73
112
|
*
|
|
@@ -13,15 +13,23 @@ import { selectorArgsToStateKey, onSubKey } from './utils';
|
|
|
13
13
|
type Action =
|
|
14
14
|
| ReturnType< typeof import('./actions').startResolution >
|
|
15
15
|
| ReturnType< typeof import('./actions').finishResolution >
|
|
16
|
+
| ReturnType< typeof import('./actions').failResolution >
|
|
16
17
|
| ReturnType< typeof import('./actions').startResolutions >
|
|
17
18
|
| ReturnType< typeof import('./actions').finishResolutions >
|
|
19
|
+
| ReturnType< typeof import('./actions').failResolutions >
|
|
18
20
|
| ReturnType< typeof import('./actions').invalidateResolution >
|
|
19
21
|
| ReturnType< typeof import('./actions').invalidateResolutionForStore >
|
|
20
22
|
| ReturnType<
|
|
21
23
|
typeof import('./actions').invalidateResolutionForStoreSelector
|
|
22
24
|
>;
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
type StateKey = unknown[] | unknown;
|
|
27
|
+
export type StateValue =
|
|
28
|
+
| { status: 'resolving' | 'finished' }
|
|
29
|
+
| { status: 'error'; error: Error | unknown };
|
|
30
|
+
|
|
31
|
+
export type Status = StateValue[ 'status' ];
|
|
32
|
+
export type State = EquivalentKeyMap< StateKey, StateValue >;
|
|
25
33
|
|
|
26
34
|
/**
|
|
27
35
|
* Reducer function returning next state for selector resolution of
|
|
@@ -34,23 +42,64 @@ const subKeysIsResolved: Reducer< Record< string, State >, Action > = onSubKey<
|
|
|
34
42
|
Action
|
|
35
43
|
>( 'selectorName' )( ( state = new EquivalentKeyMap(), action: Action ) => {
|
|
36
44
|
switch ( action.type ) {
|
|
37
|
-
case 'START_RESOLUTION':
|
|
45
|
+
case 'START_RESOLUTION': {
|
|
46
|
+
const nextState = new EquivalentKeyMap( state );
|
|
47
|
+
nextState.set( selectorArgsToStateKey( action.args ), {
|
|
48
|
+
status: 'resolving',
|
|
49
|
+
} );
|
|
50
|
+
return nextState;
|
|
51
|
+
}
|
|
38
52
|
case 'FINISH_RESOLUTION': {
|
|
39
|
-
const isStarting = action.type === 'START_RESOLUTION';
|
|
40
53
|
const nextState = new EquivalentKeyMap( state );
|
|
41
|
-
nextState.set( selectorArgsToStateKey( action.args ),
|
|
54
|
+
nextState.set( selectorArgsToStateKey( action.args ), {
|
|
55
|
+
status: 'finished',
|
|
56
|
+
} );
|
|
57
|
+
return nextState;
|
|
58
|
+
}
|
|
59
|
+
case 'FAIL_RESOLUTION': {
|
|
60
|
+
const nextState = new EquivalentKeyMap( state );
|
|
61
|
+
nextState.set( selectorArgsToStateKey( action.args ), {
|
|
62
|
+
status: 'error',
|
|
63
|
+
error: action.error,
|
|
64
|
+
} );
|
|
65
|
+
return nextState;
|
|
66
|
+
}
|
|
67
|
+
case 'START_RESOLUTIONS': {
|
|
68
|
+
const nextState = new EquivalentKeyMap( state );
|
|
69
|
+
for ( const resolutionArgs of action.args ) {
|
|
70
|
+
nextState.set( selectorArgsToStateKey( resolutionArgs ), {
|
|
71
|
+
status: 'resolving',
|
|
72
|
+
} );
|
|
73
|
+
}
|
|
42
74
|
return nextState;
|
|
43
75
|
}
|
|
44
|
-
case 'START_RESOLUTIONS':
|
|
45
76
|
case 'FINISH_RESOLUTIONS': {
|
|
46
|
-
const isStarting = action.type === 'START_RESOLUTIONS';
|
|
47
77
|
const nextState = new EquivalentKeyMap( state );
|
|
48
78
|
for ( const resolutionArgs of action.args ) {
|
|
79
|
+
nextState.set( selectorArgsToStateKey( resolutionArgs ), {
|
|
80
|
+
status: 'finished',
|
|
81
|
+
} );
|
|
82
|
+
}
|
|
83
|
+
return nextState;
|
|
84
|
+
}
|
|
85
|
+
case 'FAIL_RESOLUTIONS': {
|
|
86
|
+
const nextState = new EquivalentKeyMap( state );
|
|
87
|
+
action.args.forEach( ( resolutionArgs, idx ) => {
|
|
88
|
+
const resolutionState: StateValue = {
|
|
89
|
+
status: 'error',
|
|
90
|
+
error: undefined,
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const error = action.errors[ idx ];
|
|
94
|
+
if ( error ) {
|
|
95
|
+
resolutionState.error = error;
|
|
96
|
+
}
|
|
97
|
+
|
|
49
98
|
nextState.set(
|
|
50
|
-
selectorArgsToStateKey( resolutionArgs ),
|
|
51
|
-
|
|
99
|
+
selectorArgsToStateKey( resolutionArgs as unknown[] ),
|
|
100
|
+
resolutionState
|
|
52
101
|
);
|
|
53
|
-
}
|
|
102
|
+
} );
|
|
54
103
|
return nextState;
|
|
55
104
|
}
|
|
56
105
|
case 'INVALIDATE_RESOLUTION': {
|
|
@@ -82,8 +131,10 @@ const isResolved = ( state: Record< string, State > = {}, action: Action ) => {
|
|
|
82
131
|
: state;
|
|
83
132
|
case 'START_RESOLUTION':
|
|
84
133
|
case 'FINISH_RESOLUTION':
|
|
134
|
+
case 'FAIL_RESOLUTION':
|
|
85
135
|
case 'START_RESOLUTIONS':
|
|
86
136
|
case 'FINISH_RESOLUTIONS':
|
|
137
|
+
case 'FAIL_RESOLUTIONS':
|
|
87
138
|
case 'INVALIDATE_RESOLUTION':
|
|
88
139
|
return subKeysIsResolved( state, action );
|
|
89
140
|
}
|