chizu 0.2.57 → 0.2.58

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
@@ -11,4 +11,3 @@ export * as utils from './utils/index.ts';
11
11
  export type { Box } from 'immertation';
12
12
  export type { Fault, Catcher } from './error/index.tsx';
13
13
  export type { Pk, Task, Tasks, Handlers } from './types/index.ts';
14
- export type { CacheId, ChanneledCacheId } from './cache/index.ts';
@@ -646,6 +646,30 @@ export type HandlerContext<M extends Model, _AC extends Actions, D extends Props
646
646
  * @see {@link Handlers} for the recommended HKT pattern
647
647
  */
648
648
  export type Handler<M extends Model, AC extends Actions, K extends keyof AC, D extends Props = Props> = (context: HandlerContext<M, AC, D>, payload: Payload<AC[K] & HandlerPayload<unknown>>) => void | Promise<void> | AsyncGenerator | Generator;
649
+ /**
650
+ * Resolves the action value at a (possibly dot-notated) path within an actions object.
651
+ * For a simple key like `"SetName"`, returns `AC["SetName"]`.
652
+ * For a dotted key like `"Broadcast.PaymentSent"`, recursively resolves to
653
+ * `AC["Broadcast"]["PaymentSent"]`.
654
+ *
655
+ * @template AC - The actions object to traverse
656
+ * @template K - The key path (may contain dots)
657
+ */
658
+ type DeepAction<AC, K extends string> = K extends `${infer Head}.${infer Tail}` ? Head extends keyof AC ? DeepAction<AC[Head], Tail> : never : K extends keyof AC ? AC[K] : never;
659
+ /**
660
+ * Produces a union of all valid dot-notated key paths that resolve to leaf actions
661
+ * (i.e. values with `Brand.Action`) within an actions object.
662
+ *
663
+ * Flat actions like `SetName` produce `"SetName"`.
664
+ * Nested namespaces like `Broadcast = { PaymentSent, PaymentLink }` produce
665
+ * `"Broadcast.PaymentSent" | "Broadcast.PaymentLink"`.
666
+ *
667
+ * @template AC - The actions object to flatten
668
+ * @template Prefix - Accumulated prefix for recursion (defaults to never)
669
+ */
670
+ type FlattenKeys<AC, Prefix extends string = never> = {
671
+ [K in keyof AC & string]: AC[K] extends HandlerPayload ? [Prefix] extends [never] ? K : `${Prefix}.${K}` : FlattenKeys<AC[K], [Prefix] extends [never] ? K : `${Prefix}.${K}`>;
672
+ }[keyof AC & string];
649
673
  /**
650
674
  * Higher-Kinded Type (HKT) emulation for action handlers.
651
675
  * Creates a mapped type where each action key maps to its fully-typed handler.
@@ -653,46 +677,37 @@ export type Handler<M extends Model, AC extends Actions, K extends keyof AC, D e
653
677
  * TypeScript doesn't natively support HKTs (types that return types), but this
654
678
  * pattern emulates them using mapped types with indexed access.
655
679
  *
680
+ * Supports both flat and nested action classes with dot notation:
681
+ *
656
682
  * @template M - The model type
657
683
  * @template AC - The actions class type
658
684
  * @template D - Optional data/props type (defaults to Props)
659
685
  *
660
686
  * @example
661
687
  * ```ts
662
- * import { Action, Handlers } from "chizu";
688
+ * import { Action, Distribution, Handlers } from "chizu";
689
+ *
690
+ * class BroadcastActions {
691
+ * static PaymentSent = Action("PaymentSent", Distribution.Broadcast);
692
+ * static PaymentLink = Action<PaymentLinkData>("PaymentLink", Distribution.Broadcast);
693
+ * }
663
694
  *
664
695
  * class Actions {
665
696
  * static SetName = Action<string>("SetName");
666
- * static SetAge = Action<number>("SetAge");
697
+ * static Broadcast = BroadcastActions;
667
698
  * }
668
699
  *
669
- * // Define the HKT once for this module
670
700
  * type H = Handlers<Model, typeof Actions>;
671
701
  *
672
- * // "Apply" the HKT via indexed access — H["SetName"] is the handler type
673
- * export const handleSetName: H["SetName"] = (context, name) => {
674
- * context.actions.produce((draft) => {
675
- * draft.model.name = name;
676
- * });
677
- * };
702
+ * // Flat actions work as before
703
+ * export const handleSetName: H["SetName"] = (context, name) => { ... };
678
704
  *
679
- * export const handleSetAge: H["SetAge"] = (context, age) => {
680
- * context.actions.produce((draft) => {
681
- * draft.model.age = age;
682
- * });
683
- * };
684
- *
685
- * // Use in component
686
- * export default function useUserActions() {
687
- * const actions = useActions<Model, typeof Actions>(model);
688
- * actions.useAction(Actions.SetName, handleSetName);
689
- * actions.useAction(Actions.SetAge, handleSetAge);
690
- * return actions;
691
- * }
705
+ * // Nested actions use dot notation
706
+ * export const handlePaymentSent: H["Broadcast.PaymentSent"] = (context) => { ... };
692
707
  * ```
693
708
  */
694
709
  export type Handlers<M extends Model, AC extends Actions, D extends Props = Props> = {
695
- [K in keyof AC]: (context: HandlerContext<M, AC, D>, payload: Payload<AC[K] & HandlerPayload<unknown>>) => void | Promise<void> | AsyncGenerator | Generator;
710
+ [K in FlattenKeys<AC>]: (context: HandlerContext<M, AC, D>, payload: Payload<DeepAction<AC, K> & HandlerPayload<unknown>>) => void | Promise<void> | AsyncGenerator | Generator;
696
711
  };
697
712
  export type UseActions<M extends Model, AC extends Actions, D extends Props = Props> = [
698
713
  Readonly<M>,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chizu",
3
- "version": "0.2.57",
3
+ "version": "0.2.58",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "packageManager": "yarn@1.22.22",