mobx-keystone
Version:
A MobX powered state management solution based on data trees with first class support for TypeScript, snapshots, patches and much more
62 lines (51 loc) • 1.86 kB
text/typescript
import { AnyFunction } from "../utils/AnyFunction"
import { ActionContextActionType } from "../action/context"
import { isModelAction } from "../action/isModelAction"
import { flow, isModelFlow } from "../action/modelFlow"
import { wrapInAction } from "../action/wrapInAction"
import { assertIsTreeNode } from "../tweaker/core"
import { assertIsFunction, failure, logWarning } from "../utils"
/**
* A function with an object as target.
*/
type TargetedAction = AnyFunction
const standaloneActionRegistry = new Map<string, TargetedAction>()
/**
* @internal
*/
export function getStandaloneAction(actionName: string) {
return standaloneActionRegistry.get(actionName)
}
/**
* @internal
*/
export function addStandaloneAction(fullActionName: string, fn: TargetedAction, isFlow: boolean) {
assertIsFunction(fn, fullActionName)
if (standaloneActionRegistry.has(fullActionName)) {
logWarning(
"warn",
`an standalone action with name "${fullActionName}" already exists (if you are using hot-reloading you may safely ignore this warning)`,
`duplicateActionName - ${fullActionName}`
)
}
if (isModelAction(fn)) {
throw failure("the standalone action must not be previously marked as an action")
}
if (isModelFlow(fn)) {
throw failure("the standalone action must not be previously marked as a flow action")
}
const wrappedAction = isFlow
? flow({ nameOrNameFn: fullActionName, generator: fn })
: wrapInAction({
nameOrNameFn: fullActionName,
fn,
actionType: ActionContextActionType.Sync,
})
const finalAction = (target: any, ...args: any[]) => {
assertIsTreeNode(target, "target")
// we need to put the target into this
return wrappedAction.call(target, target, ...args)
}
standaloneActionRegistry.set(fullActionName, finalAction)
return finalAction
}