@sladg/apex-state 3.0.2 → 3.0.3

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.d.ts CHANGED
@@ -223,6 +223,40 @@ type ArrayOfChanges<DATA, META extends GenericMeta = GenericMeta> = {
223
223
  * their return types for proper type-safe concern registration and reading.
224
224
  */
225
225
 
226
+ /**
227
+ * Config type for the validationState concern at a specific path.
228
+ *
229
+ * Defined here (not in concerns/prebuilts/validation-state.ts) to avoid
230
+ * circular imports when used in ConcernRegistrationMap.
231
+ *
232
+ * Can be a schema for the path's own value type, or a scoped schema
233
+ * targeting a different path in the same state.
234
+ */
235
+ type ValidationStateInput<DATA, PATH extends DeepKey<DATA>> = {
236
+ schema: z.ZodSchema<DeepValue<DATA, PATH>>;
237
+ } | {
238
+ [SCOPE in DeepKey<DATA>]: {
239
+ scope: SCOPE;
240
+ schema: z.ZodSchema<DeepValue<DATA, SCOPE>>;
241
+ };
242
+ }[DeepKey<DATA>];
243
+ /**
244
+ * Get the appropriate registration config type for a concern at a given path.
245
+ *
246
+ * - validationState: schema must match DeepValue<DATA, PATH> — path-dependent
247
+ * - BoolLogic-based concerns: boolLogic paths are typed against DATA
248
+ * - Template-based concerns: fixed { template: string }
249
+ * - Custom concerns: fall back to Record<string, unknown>
250
+ */
251
+ type ConcernConfigFor<C, DATA extends object, PATH extends DeepKey<DATA>> = C extends {
252
+ name: 'validationState';
253
+ } ? ValidationStateInput<DATA, PATH> : C extends {
254
+ evaluate: (props: infer P) => any;
255
+ } ? P extends {
256
+ boolLogic: any;
257
+ } ? {
258
+ boolLogic: BoolLogic<DATA>;
259
+ } : Omit<P, 'state' | 'path' | 'value'> : Record<string, unknown>;
226
260
  /**
227
261
  * Extract the return type from a concern's evaluate function
228
262
  *
@@ -261,8 +295,12 @@ type EvaluatedConcerns<CONCERNS extends readonly any[]> = {
261
295
  /**
262
296
  * Maps field paths to per-concern config objects.
263
297
  *
264
- * Used as the `registration` parameter for `useConcerns` / `registerConcernEffects`.
265
- * Each key is a `DeepKey<DATA>` path, and the value maps concern names to their config.
298
+ * When CONCERNS is provided (e.g., from createGenericStore's CONCERNS generic),
299
+ * each concern config is type-checked against:
300
+ * - The concern's own EXTRA_PROPS (e.g., `{ boolLogic: ... }` for disabledWhen)
301
+ * - The path's value type for validationState (schema must match DeepValue<DATA, PATH>)
302
+ *
303
+ * Without CONCERNS (standalone usage), falls back to loose typing for backward compatibility.
266
304
  *
267
305
  * @example
268
306
  * ```typescript
@@ -272,7 +310,13 @@ type EvaluatedConcerns<CONCERNS extends readonly any[]> = {
272
310
  * }
273
311
  * ```
274
312
  */
275
- type ConcernRegistrationMap<DATA extends object> = Partial<Record<DeepKey<DATA>, Partial<Record<string, unknown>>>>;
313
+ type ConcernRegistrationMap<DATA extends object, CONCERNS extends readonly any[] = readonly any[]> = Partial<{
314
+ [PATH in DeepKey<DATA>]: Partial<{
315
+ [C in CONCERNS[number] as C extends {
316
+ name: string;
317
+ } ? C['name'] : never]: ConcernConfigFor<C, DATA, PATH>;
318
+ }>;
319
+ }>;
276
320
 
277
321
  /**
278
322
  * DeepKeyFiltered - Filters paths by their resolved value type
@@ -384,8 +428,8 @@ interface BaseConcernProps<STATE, PATH extends string> {
384
428
  path: PATH;
385
429
  value: unknown;
386
430
  }
387
- interface ConcernType<EXTRA_PROPS = Record<string, unknown>, RETURN_TYPE = unknown> {
388
- name: string;
431
+ interface ConcernType<NAME extends string = string, EXTRA_PROPS = Record<string, unknown>, RETURN_TYPE = unknown> {
432
+ name: NAME;
389
433
  description: string;
390
434
  /** Evaluated inside effect() - all state accesses are tracked */
391
435
  evaluate: (props: BaseConcernProps<Record<string, unknown>, string> & EXTRA_PROPS) => RETURN_TYPE;
@@ -770,14 +814,6 @@ interface ValidationStateResult {
770
814
  isError: boolean;
771
815
  errors: ValidationError[];
772
816
  }
773
- type ValidationStateInput<SUB_STATE, PATH extends DeepKey<SUB_STATE>> = {
774
- schema: z.ZodSchema<DeepValue<SUB_STATE, PATH>>;
775
- } | {
776
- [SCOPE in DeepKey<SUB_STATE>]: {
777
- scope: SCOPE;
778
- schema: z.ZodSchema<DeepValue<SUB_STATE, SCOPE>>;
779
- };
780
- }[DeepKey<SUB_STATE>];
781
817
  interface ValidationStateConcern {
782
818
  name: 'validationState';
783
819
  description: string;
@@ -796,21 +832,21 @@ declare const findConcern: (name: string, concerns?: readonly any[]) => ConcernT
796
832
  /**
797
833
  * Default concerns provided by apex-state
798
834
  */
799
- declare const defaultConcerns: readonly [ValidationStateConcern, ConcernType<{
835
+ declare const defaultConcerns: readonly [ValidationStateConcern, ConcernType<"disabledWhen", {
800
836
  boolLogic: BoolLogic<any>;
801
- }, boolean>, ConcernType<{
837
+ }, boolean>, ConcernType<"readonlyWhen", {
802
838
  boolLogic: BoolLogic<any>;
803
- }, boolean>, ConcernType<{
839
+ }, boolean>, ConcernType<"visibleWhen", {
804
840
  boolLogic: BoolLogic<any>;
805
- }, boolean>, ConcernType<{
841
+ }, boolean>, ConcernType<"dynamicTooltip", {
806
842
  template: string;
807
- }, string>, ConcernType<{
843
+ }, string>, ConcernType<"dynamicLabel", {
808
844
  template: string;
809
- }, string>, ConcernType<{
845
+ }, string>, ConcernType<"dynamicPlaceholder", {
810
846
  template: string;
811
847
  }, string>];
812
848
 
813
- declare const disabledWhen: ConcernType<{
849
+ declare const disabledWhen: ConcernType<'disabledWhen', {
814
850
  boolLogic: BoolLogic<any>;
815
851
  }, boolean>;
816
852
 
@@ -833,7 +869,7 @@ declare const disabledWhen: ConcernType<{
833
869
  * ```
834
870
  */
835
871
 
836
- declare const readonlyWhen: ConcernType<{
872
+ declare const readonlyWhen: ConcernType<'readonlyWhen', {
837
873
  boolLogic: BoolLogic<any>;
838
874
  }, boolean>;
839
875
 
@@ -856,7 +892,7 @@ declare const readonlyWhen: ConcernType<{
856
892
  * ```
857
893
  */
858
894
 
859
- declare const visibleWhen: ConcernType<{
895
+ declare const visibleWhen: ConcernType<'visibleWhen', {
860
896
  boolLogic: BoolLogic<any>;
861
897
  }, boolean>;
862
898
 
@@ -879,7 +915,7 @@ declare const visibleWhen: ConcernType<{
879
915
  * ```
880
916
  */
881
917
 
882
- declare const dynamicLabel: ConcernType<{
918
+ declare const dynamicLabel: ConcernType<'dynamicLabel', {
883
919
  template: string;
884
920
  }, string>;
885
921
 
@@ -902,7 +938,7 @@ declare const dynamicLabel: ConcernType<{
902
938
  * ```
903
939
  */
904
940
 
905
- declare const dynamicPlaceholder: ConcernType<{
941
+ declare const dynamicPlaceholder: ConcernType<'dynamicPlaceholder', {
906
942
  template: string;
907
943
  }, string>;
908
944
 
@@ -925,24 +961,24 @@ declare const dynamicPlaceholder: ConcernType<{
925
961
  * ```
926
962
  */
927
963
 
928
- declare const dynamicTooltip: ConcernType<{
964
+ declare const dynamicTooltip: ConcernType<'dynamicTooltip', {
929
965
  template: string;
930
966
  }, string>;
931
967
 
932
968
  /**
933
969
  * All pre-built concerns as a tuple (for use with findConcern)
934
970
  */
935
- declare const prebuilts: readonly [ValidationStateConcern, ConcernType<{
971
+ declare const prebuilts: readonly [ValidationStateConcern, ConcernType<"disabledWhen", {
936
972
  boolLogic: BoolLogic<any>;
937
- }, boolean>, ConcernType<{
973
+ }, boolean>, ConcernType<"readonlyWhen", {
938
974
  boolLogic: BoolLogic<any>;
939
- }, boolean>, ConcernType<{
975
+ }, boolean>, ConcernType<"visibleWhen", {
940
976
  boolLogic: BoolLogic<any>;
941
- }, boolean>, ConcernType<{
977
+ }, boolean>, ConcernType<"dynamicTooltip", {
942
978
  template: string;
943
- }, string>, ConcernType<{
979
+ }, string>, ConcernType<"dynamicLabel", {
944
980
  template: string;
945
- }, string>, ConcernType<{
981
+ }, string>, ConcernType<"dynamicPlaceholder", {
946
982
  template: string;
947
983
  }, string>];
948
984
  /**
@@ -950,22 +986,22 @@ declare const prebuilts: readonly [ValidationStateConcern, ConcernType<{
950
986
  */
951
987
  declare const prebuiltsNamespace: {
952
988
  validationState: ValidationStateConcern;
953
- disabledWhen: ConcernType<{
989
+ disabledWhen: ConcernType<"disabledWhen", {
954
990
  boolLogic: BoolLogic<any>;
955
991
  }, boolean>;
956
- readonlyWhen: ConcernType<{
992
+ readonlyWhen: ConcernType<"readonlyWhen", {
957
993
  boolLogic: BoolLogic<any>;
958
994
  }, boolean>;
959
- visibleWhen: ConcernType<{
995
+ visibleWhen: ConcernType<"visibleWhen", {
960
996
  boolLogic: BoolLogic<any>;
961
997
  }, boolean>;
962
- dynamicTooltip: ConcernType<{
998
+ dynamicTooltip: ConcernType<"dynamicTooltip", {
963
999
  template: string;
964
1000
  }, string>;
965
- dynamicLabel: ConcernType<{
1001
+ dynamicLabel: ConcernType<"dynamicLabel", {
966
1002
  template: string;
967
1003
  }, string>;
968
- dynamicPlaceholder: ConcernType<{
1004
+ dynamicPlaceholder: ConcernType<"dynamicPlaceholder", {
969
1005
  template: string;
970
1006
  }, string>;
971
1007
  };
@@ -1085,7 +1121,7 @@ interface SideEffects<DATA extends object, META extends GenericMeta = GenericMet
1085
1121
  listeners?: ListenerRegistration<DATA, META>[];
1086
1122
  }
1087
1123
 
1088
- declare const createGenericStore: <DATA extends object, META extends GenericMeta = GenericMeta, CONCERNS extends readonly any[] = typeof defaultConcerns>(config?: StoreConfig) => {
1124
+ declare const createGenericStore: <DATA extends object, META extends GenericMeta = GenericMeta, CONCERNS extends readonly ConcernType<string, any, any>[] = typeof defaultConcerns>(config?: StoreConfig) => {
1089
1125
  Provider: {
1090
1126
  ({ initialState: rawInitialState, children, }: ProviderProps<DATA>): react_jsx_runtime.JSX.Element | null;
1091
1127
  displayName: string;
@@ -1101,12 +1137,14 @@ declare const createGenericStore: <DATA extends object, META extends GenericMeta
1101
1137
  getState: () => DATA;
1102
1138
  };
1103
1139
  useSideEffects: (id: string, effects: SideEffects<DATA, META>) => void;
1104
- useConcerns: (id: string, registration: ConcernRegistrationMap<DATA>, customConcerns?: readonly ConcernType<any, any>[]) => void;
1105
- withConcerns: <SELECTION extends Partial<Record<string, boolean>>>(selection: SELECTION) => {
1140
+ useConcerns: <CUSTOM extends readonly ConcernType<string, any, any>[] = readonly []>(id: string, registration: ConcernRegistrationMap<DATA, readonly [...CONCERNS, ...CUSTOM]>, customConcerns?: CUSTOM) => void;
1141
+ withConcerns: <SELECTION extends Partial<Record<Extract<CONCERNS[number], {
1142
+ name: string;
1143
+ }>["name"], boolean>>>(selection: SELECTION) => {
1106
1144
  useFieldStore: <P extends DeepKey<DATA>>(path: P) => {
1107
1145
  value: DATA extends readonly any[] ? DATA[number] : P extends `${infer First}.${infer Rest}` ? First extends keyof DATA ? DeepValue<DATA[First], Rest> : string extends keyof DATA ? First extends "[*]" ? DeepValue<DATA[keyof DATA & string], Rest> : unknown : unknown : P extends "[*]" ? string extends keyof DATA ? DATA[keyof DATA & string] : unknown : P extends keyof DATA ? DATA[P] : unknown;
1108
1146
  setValue: (newValue: DATA extends readonly any[] ? DATA[number] : P extends `${infer First}.${infer Rest}` ? First extends keyof DATA ? DeepValue<DATA[First], Rest> : string extends keyof DATA ? First extends "[*]" ? DeepValue<DATA[keyof DATA & string], Rest> : unknown : unknown : P extends "[*]" ? string extends keyof DATA ? DATA[keyof DATA & string] : unknown : P extends keyof DATA ? DATA[P] : unknown, meta?: META) => void;
1109
- } & { [K in keyof SELECTION as SELECTION[K] extends true ? K : never]?: K extends CONCERNS[number]["name"] ? EvaluatedConcerns<CONCERNS>[K] : never; };
1147
+ } & { [K in keyof SELECTION as SELECTION[K] extends true ? K : never]?: K extends keyof EvaluatedConcerns<CONCERNS> ? EvaluatedConcerns<CONCERNS>[K] : never; };
1110
1148
  };
1111
1149
  };
1112
1150