import type { action, computed, observable } from "mobx"; import type { ClassAccessorDecorator } from "@matchlighter/common_library/decorators/20223fills"; import { chainDecorators } from "./utils"; export const mobx: { observable?: typeof observable, computed?: typeof computed, action?: typeof action, config: { default_observability: true | false | 'shallow' | 'ref', }, } = { config: { default_observability: true, }, }; export type Observability = true | false | 'shallow' | 'ref'; export const injectObservability = (level: Observability, actualDecorator?: ClassAccessorDecorator): any => { level ??= mobx.config.default_observability; if (!level || !mobx.observable) return actualDecorator || (() => { }); let obsv_dec; if (mobx.observable) { if (level === 'shallow') { obsv_dec = mobx.observable?.shallow; } else if (level === 'ref') { obsv_dec = mobx.observable?.ref; } else if (level) { obsv_dec = mobx.observable; } } return (value: any, context: ClassMemberDecoratorContext) => { return chainDecorators(value, context, [ obsv_dec, actualDecorator, ]); } } export type Hooks = { "construct": [any], } type Hook = keyof Hooks; const SYMBOL_HOOKS = Symbol('hooks'); export function hook(cls: any, hook: T, callback: (args: Hooks[T]) => void) { cls[SYMBOL_HOOKS] ??= {}; cls[SYMBOL_HOOKS][hook] ??= []; cls[SYMBOL_HOOKS][hook].push(callback); } hook.run = (cls: any, hook: T, args: Hooks[T]) => { const hooks = cls[SYMBOL_HOOKS]?.[hook]; if (hooks) { for (let h of hooks) { h(args); } } }