mobx-keystone
Version:
A MobX powered state management solution based on data trees with first class support for TypeScript, snapshots, patches and much more
57 lines (51 loc) • 1.63 kB
text/typescript
import { action } from "mobx"
import {
getModelRefId,
internalCustomRef,
RefIdResolver,
RefOnResolvedValueChange,
RefResolver,
} from "./core"
import type { RefConstructor } from "./Ref"
/**
* Custom reference options.
*/
export interface CustomRefOptions<T extends object> {
/**
* Must return the resolution for the given reference object.
*
* @param ref Reference object.
* @returns The resolved object or undefined if it could not be resolved.
*/
resolve: RefResolver<T>
/**
* Must return the ID associated to the given target object, or `undefined` if it has no ID.
* If not provided it will try to get the reference id from the model `getRefId()` method.
*
* @param target Target object.
*/
getId?: RefIdResolver
/**
* What should happen when the resolved value changes.
*
* @param ref Reference object.
* @param newValue New resolved value.
* @param oldValue Old resolved value.
*/
onResolvedValueChange?: RefOnResolvedValueChange<T>
}
/**
* Creates a custom ref to an object, which in its snapshot form has an id.
*
* @template T Target object type.
* @param modelTypeId Unique model type id.
* @param options Custom reference options.
* @returns A function that allows you to construct that type of custom reference.
*/
export const customRef: <T extends object>(
modelTypeId: string,
options: CustomRefOptions<T>
) => RefConstructor<T> = action("customRef", (modelTypeId, options) => {
const getId = options.getId ?? getModelRefId
return internalCustomRef(modelTypeId, () => options.resolve, getId, options.onResolvedValueChange)
})