import { isObservable, remove } from "mobx" import { toTreeNode } from "../tweaker/tweak" import { assertIsObject, namespace as ns } from "../utils" import type { AnyFunction } from "../utils/AnyFunction" import { setIfDifferent } from "../utils/setIfDifferent" import { standaloneAction } from "./standaloneActions" const namespace = `${ns}/objectActions` export const objectActions = { set: standaloneAction( `${namespace}::set`, (target: T, key: K, value: T[K]): void => { if (isObservable(target)) { setIfDifferent(target, key, value) } else { target[key] = value } } ), assign: standaloneAction( `${namespace}::assign`, (target: T, partialObject: Partial): void => { assertIsObject(partialObject, "partialObject") const keys = Object.keys(partialObject) if (isObservable(target)) { for (const key of keys) { const newValue = (partialObject as any)[key] setIfDifferent(target, key, newValue) } } else { for (const key of keys) { ;(target as any)[key] = (partialObject as any)[key] } } } ), delete: standaloneAction( `${namespace}::delete`, (target: T, key: K): boolean => { return remove(target, key as any) } ), call: standaloneAction( `${namespace}::call`, ( target: T, methodName: K, ...args: T[K] extends AnyFunction ? Parameters : never ): T[K] extends AnyFunction ? ReturnType : never => { return (target as any)[methodName](...args) } ), create: (data: T): T => toTreeNode(data), }