cogsbox-state 0.5.478 → 0.5.480

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/src/CogsState.tsx CHANGED
@@ -100,7 +100,15 @@ export type InsertTypeObj<T> = (payload: InsertParams<T>) => void;
100
100
  type EffectFunction<T, R> = (state: T, deps: any[]) => R;
101
101
  export type PerPathFormOptsType<
102
102
  TState,
103
- TPlugins extends readonly CogsPlugin<any, any, any, any, any>[] = [],
103
+ TPlugins extends readonly CogsPlugin<
104
+ any,
105
+ any,
106
+ any,
107
+ any,
108
+ any,
109
+ any,
110
+ any
111
+ >[] = [],
104
112
  > = Omit<FormOptsType, 'formElements'> & {
105
113
  formElements?: FormsElementsType<TState, TPlugins>;
106
114
  };
@@ -128,7 +136,15 @@ export type ArrayElementExtras<TParentArray = unknown> = {
128
136
  // EndType - NO $cutThis here, it's purely contextual
129
137
  export type EndType<
130
138
  T,
131
- TPlugins extends readonly CogsPlugin<any, any, any, any, any>[] = [],
139
+ TPlugins extends readonly CogsPlugin<
140
+ any,
141
+ any,
142
+ any,
143
+ any,
144
+ any,
145
+ any,
146
+ any
147
+ >[] = [],
132
148
  > = {
133
149
  $getPluginMetaData: (pluginName: string) => Record<string, any>;
134
150
  $addPluginMetaData: (key: string, data: Record<string, any>) => void;
@@ -196,12 +212,20 @@ export type EndType<
196
212
  export type ArrayElementState<
197
213
  TElement,
198
214
  TParentArray,
199
- TPlugins extends readonly CogsPlugin<any, any, any, any, any>[] = [],
215
+ TPlugins extends readonly CogsPlugin<
216
+ any,
217
+ any,
218
+ any,
219
+ any,
220
+ any,
221
+ any,
222
+ any
223
+ >[] = [],
200
224
  > = StateObject<TElement, TPlugins> & ArrayElementExtras<TParentArray>;
201
225
 
202
226
  export type ArrayEndType<
203
227
  TShape extends unknown,
204
- TPlugins extends readonly CogsPlugin<any, any, any, any, any>[],
228
+ TPlugins extends readonly CogsPlugin<any, any, any, any, any, any, any>[],
205
229
  > = {
206
230
  (): TShape;
207
231
  (newValue: TShape | ((prev: TShape) => TShape)): void;
@@ -305,7 +329,15 @@ export type ArrayEndType<
305
329
 
306
330
  export type StateObject<
307
331
  T,
308
- TPlugins extends readonly CogsPlugin<any, any, any, any, any>[] = [],
332
+ TPlugins extends readonly CogsPlugin<
333
+ any,
334
+ any,
335
+ any,
336
+ any,
337
+ any,
338
+ any,
339
+ any
340
+ >[] = [],
309
341
  > = {
310
342
  (): T;
311
343
  (newValue: T | ((prev: T) => T)): void;
@@ -349,7 +381,7 @@ type UnionToIntersection<T> = (
349
381
  : never;
350
382
 
351
383
  type PluginChainMethodCallables<
352
- TPlugins extends readonly CogsPlugin<any, any, any, any, any>[],
384
+ TPlugins extends readonly CogsPlugin<any, any, any, any, any, any, any>[],
353
385
  > = UnionToIntersection<
354
386
  TPlugins[number] extends CogsPlugin<any, any, any, any, any, infer TMethods>
355
387
  ? ChainMethodCallables<TMethods>
@@ -427,7 +459,15 @@ type SyncOptionsType<TApiParams> = {
427
459
 
428
460
  export type CreateStateOptionsType<
429
461
  T extends unknown = unknown,
430
- TPlugins extends readonly CogsPlugin<any, any, any, any, any>[] = [],
462
+ TPlugins extends readonly CogsPlugin<
463
+ any,
464
+ any,
465
+ any,
466
+ any,
467
+ any,
468
+ any,
469
+ any
470
+ >[] = [],
431
471
  > = {
432
472
  formElements?: FormsElementsType<T, TPlugins>;
433
473
  validation?: ValidationOptionsType;
@@ -490,7 +530,15 @@ type ScopedPluginApi<THookReturn, TFieldMetaData> = {
490
530
  };
491
531
  export type FormsElementsType<
492
532
  TState,
493
- TPlugins extends readonly CogsPlugin<any, any, any, any, any>[] = [],
533
+ TPlugins extends readonly CogsPlugin<
534
+ any,
535
+ any,
536
+ any,
537
+ any,
538
+ any,
539
+ any,
540
+ any
541
+ >[] = [],
494
542
  > = {
495
543
  // These optional, built-in wrappers are unchanged.
496
544
  validation?: (options: {
@@ -703,7 +751,7 @@ function setOptions<StateKey, Opt>({
703
751
  return mergedOptions;
704
752
  }
705
753
  export type PluginData = {
706
- plugin: CogsPlugin<any, any, any, any, any>;
754
+ plugin: CogsPlugin<any, any, any, any, any, any, any>;
707
755
  options: any;
708
756
  hookData?: any;
709
757
  };
@@ -712,7 +760,15 @@ export type PluginData = {
712
760
 
713
761
  export const createCogsState = <
714
762
  State extends Record<string, unknown>,
715
- const TPlugins extends readonly CogsPlugin<string, any, any, any, any>[] = [],
763
+ const TPlugins extends readonly CogsPlugin<
764
+ string,
765
+ any,
766
+ any,
767
+ any,
768
+ any,
769
+ any,
770
+ any
771
+ >[] = [],
716
772
  >(
717
773
  initialState: State,
718
774
  opt?: {
@@ -725,7 +781,7 @@ export const createCogsState = <
725
781
  useHook?: (params: { options: infer O }) => any; // infers O here
726
782
  }
727
783
  ? O
728
- : T extends CogsPlugin<string, infer O, any, any, any> // AND here
784
+ : T extends CogsPlugin<string, infer O, any, any, any, any, any> // AND here
729
785
  ? O
730
786
  : never;
731
787
 
@@ -736,24 +792,45 @@ export const createCogsState = <
736
792
  if (opt?.plugins) {
737
793
  pluginStore.getState().setRegisteredPlugins(opt.plugins as any);
738
794
  }
739
-
740
795
  type UnionToIntersection<U> = (
741
796
  U extends any ? (k: U) => void : never
742
797
  ) extends (k: infer I) => void
743
798
  ? I
744
799
  : never;
745
800
 
746
- type FullState = State &
747
- UnionToIntersection<
748
- {
749
- [K in keyof TPlugins]: TPlugins[K] extends {
750
- initialState: () => infer S;
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;
751
817
  }
752
- ? S
753
- : {};
754
- }[number]
755
- >;
756
-
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
+ >;
757
834
  const pluginState: Record<string, unknown> = {};
758
835
  if (opt?.plugins) {
759
836
  for (const plugin of opt.plugins) {
@@ -762,6 +839,7 @@ export const createCogsState = <
762
839
  }
763
840
  }
764
841
  }
842
+
765
843
  const mergedInitialState = { ...pluginState, ...initialState } as FullState;
766
844
 
767
845
  const [statePart, initialOptionsPart] =
@@ -800,10 +878,7 @@ export const createCogsState = <
800
878
  Object.keys(statePart).forEach((key) => {
801
879
  initializeShadowState(key, statePart[key]);
802
880
  });
803
- type Prettify<T> = {
804
- [K in keyof T]: T[K];
805
- } & {};
806
- type StateKeys = keyof typeof statePart;
881
+ type StateKeys = keyof FullState;
807
882
 
808
883
  // Flattens the 4x spam into a single clean object
809
884
  type CleanIntersection<T> = T extends object ? { [K in keyof T]: T[K] } : T;
@@ -815,37 +890,36 @@ export const createCogsState = <
815
890
  : never;
816
891
  }[keyof P];
817
892
 
893
+ type StateSlice<StateKey extends StateKeys> = FullState[StateKey];
894
+
818
895
  const useCogsState = <StateKey extends StateKeys>(
819
896
  stateKey: StateKey,
820
897
  options?: Prettify<
821
- OptionsType<(typeof statePart)[StateKey], never> & {
898
+ OptionsType<StateSlice<StateKey>, never> & {
822
899
  [PName in keyof PluginOptions]?: PluginOptions[PName] extends infer P
823
900
  ? P extends Record<string, any>
824
901
  ? Prettify<
825
- // 1. NON-KEYED: Partial physically forces stateRoom to be optional
826
- Partial<Pick<P, Exclude<keyof P, KeyedKeys<P>>>> &
827
- // 2. KEYED: Resolves queryParams and squashes the 4x intersection
828
- {
829
- [K in KeyedKeys<P> as StateKey extends keyof NonNullable<
830
- P[K]
831
- >['map']
832
- ? NonNullable<P[K]>['map'][StateKey] extends undefined
902
+ Partial<Pick<P, Exclude<keyof P, KeyedKeys<P>>>> & {
903
+ [K in KeyedKeys<P> as StateKey extends keyof NonNullable<
904
+ P[K]
905
+ >['map']
906
+ ? NonNullable<P[K]>['map'][StateKey] extends undefined
907
+ ? never
908
+ : keyof NonNullable<P[K]>['map'][StateKey] extends never
833
909
  ? never
834
- : keyof NonNullable<P[K]>['map'][StateKey] extends never
835
- ? never
836
- : K
837
- : never]: CleanIntersection<
838
- StateKey extends keyof NonNullable<P[K]>['map']
839
- ? NonNullable<P[K]>['map'][StateKey]
840
- : never
841
- >;
842
- }
910
+ : K
911
+ : never]: CleanIntersection<
912
+ StateKey extends keyof NonNullable<P[K]>['map']
913
+ ? NonNullable<P[K]>['map'][StateKey]
914
+ : never
915
+ >;
916
+ }
843
917
  >
844
918
  : P
845
919
  : never;
846
920
  }
847
921
  >
848
- ) => {
922
+ ): StateObject<StateSlice<StateKey>> => {
849
923
  const [componentId] = useState(options?.componentId ?? uuidv4());
850
924
 
851
925
  const currentOptions = setOptions({
@@ -860,21 +934,18 @@ export const createCogsState = <
860
934
  const thiState =
861
935
  getShadowValue(stateKey as string, []) || statePart[stateKey as string];
862
936
 
863
- const updater = useCogsStateFn<(typeof statePart)[StateKey]>(
864
- thiState,
865
- {
866
- stateKey: stateKey as string,
867
- syncUpdate: options?.syncUpdate,
868
- componentId,
869
- localStorage: options?.localStorage,
870
- middleware: options?.middleware,
871
- reactiveType: options?.reactiveType,
872
- reactiveDeps: options?.reactiveDeps,
873
- defaultState: options?.defaultState as any,
874
- dependencies: options?.dependencies,
875
- serverState: options?.serverState,
876
- }
877
- );
937
+ const updater = useCogsStateFn<StateSlice<StateKey>>(thiState, {
938
+ stateKey: stateKey as string,
939
+ syncUpdate: options?.syncUpdate,
940
+ componentId,
941
+ localStorage: options?.localStorage,
942
+ middleware: options?.middleware,
943
+ reactiveType: options?.reactiveType,
944
+ reactiveDeps: options?.reactiveDeps,
945
+ defaultState: options?.defaultState as any,
946
+ dependencies: options?.dependencies,
947
+ serverState: options?.serverState,
948
+ });
878
949
 
879
950
  useEffect(() => {
880
951
  if (options) {
@@ -893,14 +964,14 @@ export const createCogsState = <
893
964
  };
894
965
  }, [stateKey, updater]);
895
966
 
896
- return updater as StateObject<(typeof statePart)[StateKey]>;
967
+ return updater as StateObject<StateSlice<StateKey>>;
897
968
  };
898
969
 
899
970
  function setCogsOptionsByKey<StateKey extends StateKeys>(
900
971
  stateKey: StateKey,
901
- options: CreateStateOptionsType<(typeof statePart)[StateKey], TPlugins> &
972
+ options: CreateStateOptionsType<StateSlice<StateKey>, TPlugins> &
902
973
  Omit<
903
- OptionsType<(typeof statePart)[StateKey]>,
974
+ OptionsType<StateSlice<StateKey>>,
904
975
  keyof CreateStateOptionsType
905
976
  >
906
977
  ) {
@@ -1546,7 +1617,15 @@ function createEffectiveSetState<T>(
1546
1617
 
1547
1618
  export function useCogsStateFn<
1548
1619
  TStateObject extends unknown,
1549
- const TPlugins extends readonly CogsPlugin<any, any, any, any, any>[] = [],
1620
+ const TPlugins extends readonly CogsPlugin<
1621
+ any,
1622
+ any,
1623
+ any,
1624
+ any,
1625
+ any,
1626
+ any,
1627
+ any
1628
+ >[] = [],
1550
1629
  >(
1551
1630
  stateObject: TStateObject,
1552
1631
  {
@@ -2063,7 +2142,15 @@ function setFieldDisabledForPath(
2063
2142
 
2064
2143
  function createProxyHandler<
2065
2144
  T,
2066
- const TPlugins extends readonly CogsPlugin<any, any, any, any, any>[],
2145
+ const TPlugins extends readonly CogsPlugin<
2146
+ any,
2147
+ any,
2148
+ any,
2149
+ any,
2150
+ any,
2151
+ any,
2152
+ any
2153
+ >[],
2067
2154
  >(
2068
2155
  stateKey: string,
2069
2156
  effectiveSetState: EffectiveSetState<T>,
@@ -19,7 +19,7 @@ const PluginInstance = React.memo(
19
19
  stateHandler,
20
20
  }: {
21
21
  stateKey: string;
22
- plugin: CogsPlugin<any, any, any, any, any>;
22
+ plugin: CogsPlugin<any, any, any, any, any, any, any>;
23
23
  options: any;
24
24
  stateHandler: StateObject<any>;
25
25
  }) => {