cogsbox-state 0.5.480 → 0.5.481

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cogsbox-state",
3
- "version": "0.5.480",
3
+ "version": "0.5.481",
4
4
  "description": "React state management library with form controls and server sync",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/src/CogsState.tsx CHANGED
@@ -758,8 +758,138 @@ export type PluginData = {
758
758
 
759
759
  ////////////////////////////////
760
760
 
761
+ type AnyCogsPlugin = CogsPlugin<string, any, any, any, any, any, any>;
762
+
763
+ type ExtractPluginOptions<T> = T extends {
764
+ useHook?: (params: { options: infer O }) => any;
765
+ }
766
+ ? O
767
+ : T extends CogsPlugin<string, infer O, any, any, any, any, any>
768
+ ? O
769
+ : never;
770
+
771
+ type PluginOptionsMap<TPlugins extends readonly AnyCogsPlugin[]> = {
772
+ [K in TPlugins[number] as K['name']]?: ExtractPluginOptions<K>;
773
+ };
774
+
775
+ type ExtractPluginState<T> = T extends {
776
+ initialState?: () => infer S;
777
+ }
778
+ ? S extends object
779
+ ? S
780
+ : {}
781
+ : T extends CogsPlugin<string, any, any, any, any, any, infer S>
782
+ ? S extends object
783
+ ? S
784
+ : {}
785
+ : {};
786
+
787
+ type PluginStates<TPlugins extends readonly AnyCogsPlugin[]> =
788
+ UnionToIntersection<ExtractPluginState<TPlugins[number]>> extends infer S
789
+ ? S extends object
790
+ ? S
791
+ : {}
792
+ : {};
793
+
794
+ type KnownKeys<T> =
795
+ string extends keyof T
796
+ ? never
797
+ : number extends keyof T
798
+ ? never
799
+ : symbol extends keyof T
800
+ ? never
801
+ : keyof T;
802
+
803
+ type MergeInitialState<
804
+ State extends object,
805
+ PluginState extends object,
806
+ > = Prettify<
807
+ State & {
808
+ [K in keyof PluginState as K extends KnownKeys<State>
809
+ ? never
810
+ : K]: PluginState[K];
811
+ }
812
+ >;
813
+
814
+ type CogsFullState<
815
+ State extends object,
816
+ TPlugins extends readonly AnyCogsPlugin[],
817
+ > = MergeInitialState<State, PluginStates<TPlugins>>;
818
+
819
+ type CleanIntersection<T> = T extends object ? { [K in keyof T]: T[K] } : T;
820
+
821
+ type KeyedKeys<P> = {
822
+ [K in keyof P]-?: NonNullable<P[K]> extends { __key: 'keyed'; map: any }
823
+ ? K
824
+ : never;
825
+ }[keyof P];
826
+
827
+ type PluginOptionsForState<
828
+ PluginOptions,
829
+ StateKey extends PropertyKey,
830
+ > = {
831
+ [PName in keyof PluginOptions]?: PluginOptions[PName] extends infer P
832
+ ? P extends Record<string, any>
833
+ ? Prettify<
834
+ Partial<Pick<P, Exclude<keyof P, KeyedKeys<P>>>> & {
835
+ [K in KeyedKeys<P> as StateKey extends keyof NonNullable<
836
+ P[K]
837
+ >['map']
838
+ ? NonNullable<P[K]>['map'][StateKey] extends undefined
839
+ ? never
840
+ : keyof NonNullable<P[K]>['map'][StateKey] extends never
841
+ ? never
842
+ : K
843
+ : never]: CleanIntersection<
844
+ StateKey extends keyof NonNullable<P[K]>['map']
845
+ ? NonNullable<P[K]>['map'][StateKey]
846
+ : never
847
+ >;
848
+ }
849
+ >
850
+ : P
851
+ : never;
852
+ };
853
+
854
+ type UseCogsStateOptions<
855
+ StateSlice,
856
+ PluginOptions,
857
+ StateKey extends PropertyKey,
858
+ > = Prettify<
859
+ OptionsType<StateSlice, never> & PluginOptionsForState<PluginOptions, StateKey>
860
+ >;
861
+
862
+ type CreateCogsStateReturn<
863
+ State extends object,
864
+ TPlugins extends readonly AnyCogsPlugin[],
865
+ > = {
866
+ useCogsState: <StateKey extends keyof CogsFullState<State, TPlugins>>(
867
+ stateKey: StateKey,
868
+ options?: UseCogsStateOptions<
869
+ CogsFullState<State, TPlugins>[StateKey],
870
+ PluginOptionsMap<TPlugins>,
871
+ StateKey
872
+ >
873
+ ) => StateObject<CogsFullState<State, TPlugins>[StateKey]>;
874
+ setCogsOptionsByKey: <StateKey extends keyof CogsFullState<State, TPlugins>>(
875
+ stateKey: StateKey,
876
+ options: CreateStateOptionsType<
877
+ CogsFullState<State, TPlugins>[StateKey],
878
+ TPlugins
879
+ > &
880
+ Omit<
881
+ OptionsType<CogsFullState<State, TPlugins>[StateKey]>,
882
+ keyof CreateStateOptionsType
883
+ >
884
+ ) => void;
885
+ setCogsOptions: (
886
+ globalOptions: CreateStateOptionsType<unknown, TPlugins> &
887
+ Omit<OptionsType<unknown>, keyof CreateStateOptionsType>
888
+ ) => void;
889
+ };
890
+
761
891
  export const createCogsState = <
762
- State extends Record<string, unknown>,
892
+ State extends object,
763
893
  const TPlugins extends readonly CogsPlugin<
764
894
  string,
765
895
  any,
@@ -776,18 +906,8 @@ export const createCogsState = <
776
906
  formElements?: FormsElementsType<State, TPlugins>;
777
907
  validation?: ValidationOptionsType;
778
908
  }
779
- ) => {
780
- type ExtractPluginOptions<T> = T extends {
781
- useHook?: (params: { options: infer O }) => any; // infers O here
782
- }
783
- ? O
784
- : T extends CogsPlugin<string, infer O, any, any, any, any, any> // AND here
785
- ? O
786
- : never;
787
-
788
- type PluginOptions = {
789
- [K in TPlugins[number] as K['name']]?: ExtractPluginOptions<K>;
790
- };
909
+ ) : CreateCogsStateReturn<State, TPlugins> => {
910
+ type PluginOptions = PluginOptionsMap<TPlugins>;
791
911
 
792
912
  if (opt?.plugins) {
793
913
  pluginStore.getState().setRegisteredPlugins(opt.plugins as any);
@@ -798,39 +918,7 @@ export const createCogsState = <
798
918
  ? I
799
919
  : never;
800
920
 
801
- // Extract plugin initial state from the CogsPlugin generic (7th param) first,
802
- // falling back to structural inference from initialState() return type.
803
- type ExtractPluginState<T> = T extends CogsPlugin<
804
- string,
805
- any,
806
- any,
807
- any,
808
- any,
809
- any,
810
- infer S
811
- >
812
- ? S extends Record<string, unknown>
813
- ? S
814
- : {}
815
- : T extends {
816
- initialState?: () => infer S;
817
- }
818
- ? S extends Record<string, unknown>
819
- ? S
820
- : {}
821
- : {};
822
-
823
- // Extract the merged plugin states into a helper type
824
- type PluginStates = UnionToIntersection<ExtractPluginState<TPlugins[number]>>;
825
-
826
- // User keys win over plugin keys — omit overlapping plugin keys before merging.
827
- type FullState = Prettify<
828
- State & {
829
- [K in keyof PluginStates as K extends keyof State
830
- ? never
831
- : K]: PluginStates[K];
832
- }
833
- >;
921
+ type FullState = CogsFullState<State, TPlugins>;
834
922
  const pluginState: Record<string, unknown> = {};
835
923
  if (opt?.plugins) {
836
924
  for (const plugin of opt.plugins) {
@@ -876,7 +964,7 @@ export const createCogsState = <
876
964
  });
877
965
 
878
966
  Object.keys(statePart).forEach((key) => {
879
- initializeShadowState(key, statePart[key]);
967
+ initializeShadowState(key, (statePart as Record<string, unknown>)[key]);
880
968
  });
881
969
  type StateKeys = keyof FullState;
882
970
 
@@ -932,7 +1020,8 @@ export const createCogsState = <
932
1020
  optionsRef.current = currentOptions;
933
1021
 
934
1022
  const thiState =
935
- getShadowValue(stateKey as string, []) || statePart[stateKey as string];
1023
+ getShadowValue(stateKey as string, []) ||
1024
+ (statePart as Record<string, unknown>)[stateKey as string];
936
1025
 
937
1026
  const updater = useCogsStateFn<StateSlice<StateKey>>(thiState, {
938
1027
  stateKey: stateKey as string,
@@ -1021,7 +1110,7 @@ export const createCogsState = <
1021
1110
  useCogsState,
1022
1111
  setCogsOptionsByKey,
1023
1112
  setCogsOptions,
1024
- };
1113
+ } as CreateCogsStateReturn<State, TPlugins>;
1025
1114
  };
1026
1115
 
1027
1116
  const saveToLocalStorage = <T,>(