declare module "bravent" { import { Validation } from "data.validation"; // ---- Events ------ // type Event = { [P in keyof TPayload]: TPayload[P] } & { type: TEventType; }; type EventDefinitions = { [eventName: string]: TEventPayload; }; type EventFromDefinition< TEventDefinitions extends EventDefinitions, T extends keyof TEventDefinitions > = T extends keyof TEventDefinitions ? T extends string ? Event : never : never; type EventsInDefinition> = EventFromDefinition< TEventDefinitions, keyof TEventDefinitions >; type ExtractEventDefinitions = T extends AggregateClass ? X : never; type EventsFromAggregateClass = EventsInDefinition>; // ---- Commands ------ // type Command = { [P in keyof TPayload]: TPayload[P] } & { type: TCommandType; }; type CommandDefinitions = { [eventName: string]: TCommandPayload; }; type CommandFromDefinition< TCommandDefinitions extends CommandDefinitions, T extends keyof TCommandDefinitions > = T extends keyof TCommandDefinitions ? T extends string ? Command : never : never; type CommandsInDefinition< TCommandDefinitions extends CommandDefinitions > = CommandFromDefinition; type ExtractCommandDefinitions = T extends AggregateClass ? Y : never; type AnyCommandFromAggregateClass = CommandsInDefinition>; // ---- Handlers ------ // type CommandHandlerReturn> = | EventsInDefinition[] | Validation; type EventHandlers> = { [P in keyof TEventDefinitions]: ( state: TState, event: Event ) => TState }; type CommandHandlers< TState, TCommandDefinitions extends CommandDefinitions, TEventDefinitions extends EventDefinitions > = { [P in keyof TCommandDefinitions]: ( state: TState, command: Command ) => CommandHandlerReturn }; // ---- Aggregate ------ // type AnyAggregateClass = AggregateClass< any, ExtractEventDefinitions, ExtractCommandDefinitions >; type AnyAggregateInstance = AggregateInstance< any, ExtractEventDefinitions, ExtractCommandDefinitions >; type AggregateDefinition< TState, TEventDefinitions extends EventDefinitions, TCommandDefinitions extends CommandDefinitions > = { initialState?: TState; eventHandlers: EventHandlers; commandHandlers: CommandHandlers; }; type OnDispatchSuccessHandlerForAggregateClass = OnDispatchSuccessHandler< ExtractEventDefinitions >; type OnDispatchSuccessHandler> = ( newEvents: EventsInDefinition[] ) => void; type OnDispatchFailureHandler = (error: any) => {}; type AggregateInstance< TState, TEventDefinitions extends EventDefinitions, TCommandDefinitions extends CommandDefinitions > = { dispatch: ( command: CommandsInDefinition, onSuccess?: OnDispatchSuccessHandler, onFailure?: OnDispatchFailureHandler ) => AggregateInstance; state: () => TState; }; type AggregateClass< TState, TEventDefinitions extends EventDefinitions, TCommandDefinitions extends CommandDefinitions > = { of: ( events: EventsInDefinition[] ) => AggregateInstance; }; export function defineAggregate< TState, TEventDefinitions extends EventDefinitions, TCommandDefinitions extends CommandDefinitions >( definition: AggregateDefinition ): AggregateClass; }