import { IComputedValueOptions } from 'mobx'; import { Merge, SetOptional } from 'type-fest'; import { Dispose } from '../../utils/disposable'; import { PrependArgument } from '../../utils/PrependArgument'; import { NodeTypeKey, NodeTypeValue, nodeTypeKey } from './nodeType'; /** * Base interface for node types with type-specific capabilities. * * @template TNode - The object type representing a node * @template TCapabilities - Node type capabilities, can be "typed" and/or "keyed" * @template TOptional - Optional properties of the node type * @template TKey - Property key used for node identification (if keyed) * @template TOther - Additional type information */ interface BaseNodeTypeWithType { /** * Unique identifier for this node type */ typeId: TNode extends { [nodeTypeKey]: NodeTypeValue; } ? TNode[NodeTypeKey] : undefined; /** * Checks if the node is of a specific type * * @param node - Node to check * @returns true if the node type matches, false otherwise */ nodeIsOfType(node: object): node is TNode; /** * Unregisters this node type */ unregister(): void; /** * Unregisters this node type (disposable pattern) */ [Symbol.dispose](): void; /** * Registers a callback to run when nodes of this type are initialized * * @param callback - Function to execute when a node is initialized * * @returns The same node type with the added initialization callback */ onInit(callback: (node: TNode) => void): BaseNodeType; _initNode(node: TNode): void; _addOnInit(callback: (node: TNode) => void): Dispose; /** * Configures this type to use a specific property as the node key * * @template TKey - Property key in the node type * @param key - Property name to use as the node key * @returns A keyed node type using the specified property as key */ withKey(key: TKey): BaseNodeType; /** * Makes this node type immutable. * * Immutable nodes cannot be modified after creation and sub-objects are not turned into nodes. * This is useful for creating read-only nodes or for performance optimizations. */ frozen(): BaseNodeType; /** * true if the node type is frozen, false otherwise */ isFrozen: boolean; } /** * Interface that represents a node type with a key property. * Provides functionality for accessing and finding nodes by their unique keys. * * @template TNode - The node type * @template TKey - The key of the node's unique identifier property */ interface BaseNodeTypeWithKey { /** * Property name containing the node's unique key */ key: TKey; /** * Gets the unique key value for a node * * @param node - Node to get the key from * @returns The node's key value or undefined */ getKey(node: TNode): TNode[TKey] | undefined; /** * Retrieves a node by its key (if it exists) * * @param key - Key to search for * @returns The node with the specified key or undefined */ findByKey(key: TNode[TKey]): TNode | undefined; } /** * Base node type definition with core functionality * * @template TNode - Node structure that adheres to this type * @template TOptional - Optional keys in the node structure * @template TCapabilities - Type of capabilities (untyped, typed or keyed) * @template TKey - Key field in the node structure (if any) * @template TOther - Additional properties and methods */ export type BaseNodeType = { /** * Node constructor. * Requires all keys from TNode except those in TOptional (which may be omitted). */ (data: SetOptional): TNode; /** * Returns a snapshot based on the provided data. */ snapshot(data: SetOptional): TNode; /** * Adds volatile state properties to nodes of this type * * Volatile state is not persisted in snapshots and is local to each node instance. * * @template TVolatiles - Record of volatile property getter functions * @param volatile - Object where each key defines a getter function for volatile state * @returns The same NodeType with added accessor methods for the volatile state */ volatile any>>(volatile: TVolatiles): BaseNodeType>>; /** * Registers action methods for nodes of this type * * Actions are methods that can modify the node state and are automatically * wrapped in MobX actions for proper state tracking. * * @template TActions - Record of action methods * * @param actions - An object of action methods * * @returns The same NodeType with added action methods that accept a node as their first parameter */ actions any>>(actions: TActions): BaseNodeType; }>>; /** * Registers getter methods for nodes of this type * * Getters are methods that derive values from the node state without modifying it. * * @template TGetters - Record of getter methods * * @param getters - An object of getter methods * * @returns The same NodeType with added getter methods that accept a node as their first parameter */ getters any>>(getters: TGetters): BaseNodeType; }>>; /** * Registers computed methods for nodes of this type * * Computed methods derive values from the node state and are automatically * memoized by MobX for performance optimization. * * @template TComputeds - Record of computed properties * @param computeds - Function that receives a node and returns an object of computed accessor methods * @returns The same NodeType with added computed methods that accept a node as their first parameter */ computeds>>(computeds: TComputeds): BaseNodeType any ? PrependArgument : TComputeds[k] extends ComputedFnWithOptions ? PrependArgument : never; }>>; /** * Generates setter methods for specified properties * * @param properties - Names of properties to create setters for * @returns The same NodeType with added setter methods */ settersFor(...properties: readonly K[]): BaseNodeType}`]: (node: TNode, value: Readonly) => void; }>>; /** * Define default values for keys in TOptional. * When omitted, those properties are filled with the results of these generators. * * @template TGen - Record of default value generators */ defaults TNode[K]; }>(defaultGenerators: TGen): BaseNodeType; /** * Default generators defined so far. */ defaultGenerators?: { [K in keyof TNode]?: () => TNode[K]; }; /** * Extend this type from another untyped node type. * The base node type can be a subset of the current node type. * * @template TBaseNode - Base node type (must be a subset of TNode) * @template TExtendedOther - Additional properties and methods from the base type * @param nodeType - Node type to extend from */ extends(nodeType: BaseNodeType): TNode extends TExtendedNode ? BaseNodeType> : never; _extendsKeys: Set; } & (TCapabilities extends "typed" | "keyed" ? BaseNodeTypeWithType & (TCapabilities extends "keyed" ? BaseNodeTypeWithKey : unknown) : unknown) & TOther; /** * Configuration for a computed property with options * * @template TThis - This type for the computed function * @template T - Return type of the computed value */ export type ComputedFnWithOptions = { get: (this: TThis) => T; } & Omit, "get" | "set">; /** * Computed property definition that can be a function or configuration object * * @template TThis - This type for the computed function * @template T - Return type of the computed value */ export type ComputedEntry = ((this: TThis) => T) | ComputedFnWithOptions; /** * Generates accessor methods for volatile properties * * @template T - Record of volatile property getter functions * @template TNode - The node type these accessors operate on */ export type VolatileAccessors any>, TNode> = { [K in keyof T as `set${Capitalize}`]: (n: TNode, value: ReturnType) => void; } & { [K in keyof T as `get${Capitalize}`]: (n: TNode) => ReturnType; } & { [K in keyof T as `reset${Capitalize}`]: (n: TNode) => void; }; export {};