import { createAction, executeAction, Annotation, die, isFunction, isStringish, createActionAnnotation, decorateAction20223_, assign } from "../internal" import { createDecoratorAnnotation, type DecoratorAnnotation } from "./decoratorannotation" import type { ClassMethodAndFieldDecorator } from "../types/decorator_fills" export const ACTION = "action" export const ACTION_BOUND = "action.bound" export const AUTOACTION = "autoAction" export const AUTOACTION_BOUND = "autoAction.bound" const DEFAULT_ACTION_NAME = "" const actionAnnotation = createActionAnnotation(ACTION) const actionBoundAnnotation = createActionAnnotation(ACTION_BOUND, { bound: true }) const autoActionAnnotation = createActionAnnotation(AUTOACTION, { autoAction: true }) const autoActionBoundAnnotation = createActionAnnotation(AUTOACTION_BOUND, { autoAction: true, bound: true }) function createActionDecoratorAnnotation( annotation: Annotation ): DecoratorAnnotation { return createDecoratorAnnotation(annotation, decorateAction20223_) } export interface IActionFactory extends Annotation, ClassMethodAndFieldDecorator { // nameless actions (fn: T): T // named actions (name: string, fn: T): T // named annotation (customName: string): DecoratorAnnotation } function createActionFactory(autoAction: boolean): IActionFactory { const res: IActionFactory = function action(arg1, arg2?): any { if (arg2 && typeof arg2.kind === "string") { return decorateAction20223_( autoAction ? autoActionAnnotation : actionAnnotation, arg1, arg2 ) } // action(fn() {}) if (isFunction(arg1)) { return createAction(arg1.name || DEFAULT_ACTION_NAME, arg1, autoAction) } // action("name", fn() {}) if (isFunction(arg2)) { return createAction(arg1, arg2, autoAction) } // action("name") annotation if (isStringish(arg1)) { return createActionDecoratorAnnotation( createActionAnnotation(autoAction ? AUTOACTION : ACTION, { name: arg1, autoAction }) ) } if (__DEV__) { die("Invalid arguments for `action`") } } as IActionFactory return res } export const action: IActionFactory = createActionFactory(false) assign(action, actionAnnotation) export const autoAction: IActionFactory = createActionFactory(true) assign(autoAction, autoActionAnnotation) export const actionBound = createActionDecoratorAnnotation(actionBoundAnnotation) export const autoActionBound = createActionDecoratorAnnotation(autoActionBoundAnnotation) export function runInAction(fn: () => T): T { return executeAction(fn.name || DEFAULT_ACTION_NAME, false, fn, this, undefined) } export function isAction(thing: any) { return isFunction(thing) && thing.isMobxAction === true }