import type { ActionOptions } from '../lib/teact/teactn'; import { typify } from '../lib/teact/teactn'; import type { ActionPayloads, GlobalState, RequiredActionPayloads, RequiredGlobalState, } from './types'; const typed = typify(); type ProjectActionTypes = ActionPayloads & RequiredActionPayloads; type ProjectActionNames = keyof ProjectActionTypes; type Helper = Exclude extends never ? unknown : Exclude; export type TabStateActionNames = { [ActionName in ProjectActionNames]: 'tabId' extends keyof Helper ? ActionName : never }[ProjectActionNames]; // `Required` actions are called from actions to ensure the `tabId` is always provided if needed. // There are three types of actions: // 1. With tabId, which is made required when calling action from another action handler // 2. Without payload (= undefined), hence made the payload not required // 3. With payload, hence made the payload required export type RequiredGlobalActions = { [ActionName in ProjectActionNames]: ActionName extends TabStateActionNames ? (( payload: ProjectActionTypes[ActionName] & { tabId: number }, options?: ActionOptions, ) => void) : (undefined extends ProjectActionTypes[ActionName] ? ( (payload?: ProjectActionTypes[ActionName], options?: ActionOptions) => void ) : ( (payload: ProjectActionTypes[ActionName], options?: ActionOptions) => void )) } & { _: never }; type ActionHandlers = { [ActionName in keyof ProjectActionTypes]: ( global: RequiredGlobalState, actions: RequiredGlobalActions, payload: ProjectActionTypes[ActionName], ) => GlobalState | void | Promise; }; export const getGlobal = typed.getGlobal; export const setGlobal = typed.setGlobal; export const getActions = typed.getActions; export const getPromiseActions = typed.getPromiseActions; export const addActionHandler = typed.addActionHandler as ( name: ActionName, handler: ActionHandlers[ActionName], ) => void; export const withGlobal = typed.withGlobal; export type GlobalActions = ReturnType;