UNPKG

2.73 kBPlain TextView Raw
1import {
2 createAction,
3 executeAction,
4 Annotation,
5 storeAnnotation,
6 die,
7 isFunction,
8 isStringish,
9 createDecoratorAnnotation,
10 createActionAnnotation
11} from "../internal"
12
13export const ACTION = "action"
14export const ACTION_BOUND = "action.bound"
15export const AUTOACTION = "autoAction"
16export const AUTOACTION_BOUND = "autoAction.bound"
17
18const DEFAULT_ACTION_NAME = "<unnamed action>"
19
20const actionAnnotation = createActionAnnotation(ACTION)
21const actionBoundAnnotation = createActionAnnotation(ACTION_BOUND, {
22 bound: true
23})
24const autoActionAnnotation = createActionAnnotation(AUTOACTION, {
25 autoAction: true
26})
27const autoActionBoundAnnotation = createActionAnnotation(AUTOACTION_BOUND, {
28 autoAction: true,
29 bound: true
30})
31
32export interface IActionFactory extends Annotation, PropertyDecorator {
33 // nameless actions
34 <T extends Function | undefined | null>(fn: T): T
35 // named actions
36 <T extends Function | undefined | null>(name: string, fn: T): T
37
38 // named decorator
39 (customName: string): PropertyDecorator & Annotation
40
41 // decorator (name no longer supported)
42 bound: Annotation & PropertyDecorator
43}
44
45function createActionFactory(autoAction: boolean): IActionFactory {
46 const res: IActionFactory = function action(arg1, arg2?): any {
47 // action(fn() {})
48 if (isFunction(arg1))
49 return createAction(arg1.name || DEFAULT_ACTION_NAME, arg1, autoAction)
50 // action("name", fn() {})
51 if (isFunction(arg2)) return createAction(arg1, arg2, autoAction)
52 // @action
53 if (isStringish(arg2)) {
54 return storeAnnotation(arg1, arg2, autoAction ? autoActionAnnotation : actionAnnotation)
55 }
56 // action("name") & @action("name")
57 if (isStringish(arg1)) {
58 return createDecoratorAnnotation(
59 createActionAnnotation(autoAction ? AUTOACTION : ACTION, {
60 name: arg1,
61 autoAction
62 })
63 )
64 }
65
66 if (__DEV__) die("Invalid arguments for `action`")
67 } as IActionFactory
68 return res
69}
70
71export const action: IActionFactory = createActionFactory(false)
72Object.assign(action, actionAnnotation)
73export const autoAction: IActionFactory = createActionFactory(true)
74Object.assign(autoAction, autoActionAnnotation)
75
76action.bound = createDecoratorAnnotation(actionBoundAnnotation)
77autoAction.bound = createDecoratorAnnotation(autoActionBoundAnnotation)
78
79export function runInAction<T>(fn: () => T): T {
80 return executeAction(fn.name || DEFAULT_ACTION_NAME, false, fn, this, undefined)
81}
82
83export function isAction(thing: any) {
84 return isFunction(thing) && thing.isMobxAction === true
85}