/** * Copyright (c) 2018-2025 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author David Sehnal */ import { Task } from '../mol-task/index.js'; import { StateObject, StateObjectCell } from './object.js'; import { StateTransform } from './transform.js'; import { ParamDefinition as PD } from '../mol-util/param-definition.js'; import { StateAction } from './action.js'; import { StateTreeSpine } from './tree/spine.js'; export { Transformer as StateTransformer }; interface Transformer { apply(parent: StateTransform.Ref, params?: P, props?: Partial): StateTransform; toAction(): StateAction; readonly namespace: string; readonly id: Transformer.Id; readonly definition: Transformer.Definition; /** create a fresh copy of the params which can be edited in place */ createDefaultParams(a: A, globalCtx: unknown): P; } declare namespace Transformer { type Id = string & { '@type': 'transformer-id'; }; type Params> = T extends Transformer ? P : unknown; type From> = T extends Transformer ? A : unknown; type To> = T extends Transformer ? B : unknown; type Cell> = T extends Transformer ? StateObjectCell : unknown; function getParamDefinition(t: T, a: From | undefined, globalCtx: unknown): PD.For>; function is(obj: any): obj is Transformer; interface ApplyParams { a: A; params: P; /** A cache object that is purged each time the corresponding StateObject is removed or recreated. */ cache: unknown; spine: StateTreeSpine; dependencies?: { [k: string]: StateObject; }; } interface UpdateParams { a: A; b: B; oldParams: P; newParams: P; /** A cache object that is purged each time the corresponding StateObject is removed or recreated. */ cache: unknown; spine: StateTreeSpine; dependencies?: { [k: string]: StateObject; }; } interface AutoUpdateParams { a: A; b: B; oldParams: P; newParams: P; } interface DisposeParams { b: B | undefined; params: P | undefined; cache: unknown; } enum UpdateResult { Unchanged = 0, Updated = 1, Recreate = 2, Null = 3 } /** Specify default control descriptors for the parameters */ interface DefinitionBase { /** * Apply the actual transformation. It must be pure (i.e. with no side effects). * Returns a task that produces the result of the result directly. */ apply(params: ApplyParams, globalCtx: unknown): Task | B; /** * Attempts to update the entity in a non-destructive way. * For example changing a color scheme of a visual does not require computing new geometry. * Return/resolve to undefined if the update is not possible. */ update?(params: UpdateParams, globalCtx: unknown): Task | UpdateResult; /** Determine if the transformer can be applied automatically on UI change. Default is false. */ canAutoUpdate?(params: AutoUpdateParams, globalCtx: unknown): boolean; /** Test if the transform can be applied to a given node */ isApplicable?(a: A, globalCtx: unknown): boolean; /** By default, returns true */ isSerializable?(params: P): { isSerializable: true; } | { isSerializable: false; reason: string; }; /** Parameter interpolation */ interpolate?(src: P, target: P, t: number, globalCtx: unknown): P; /** * Cleanup resources * * Automatically called on deleting an object and on recreating it * (i.e. when update returns UpdateResult.Recreate or UpdateResult.Null) * * Not called on UpdateResult.Updated because the resources might not * have been invalidated. In this case, the possible cleanup has to be handled * manually. */ dispose?(params: DisposeParams, globalCtx: unknown): void; /** Custom conversion to and from JSON */ readonly customSerialization?: { toJSON(params: P, obj?: B): any; fromJSON(data: any): P; }; } interface Definition extends DefinitionBase { readonly name: string; readonly from: StateObject.Ctor[]; readonly to: StateObject.Ctor[]; readonly display: { readonly name: string; readonly description?: string; }; params?(a: A | undefined, globalCtx: unknown): { [K in keyof P]: PD.Any; }; /** * Decorators are special Transformers mapping the object to the same type. * * Special rules apply: * - applying decorator always "inserts" it instead * - applying to a decorated Transform is applied to the decorator instead (transitive) */ readonly isDecorator?: boolean; } function getAll(): Transformer[]; function get(id: string): Transformer; function fromType(type: StateObject.Type): ReadonlyArray; function create(namespace: string, definition: Definition): Transformer; function factory(namespace: string): (definition: Definition) => Transformer; function builderFactory(namespace: string): Builder.Root; namespace Builder { interface Type { name: string; from: A | A[]; to: B | B[]; /** The source StateObject can be undefined: used for generating docs. */ params?: PD.For

| ((a: StateObject.From | undefined, globalCtx: any) => PD.For

); display?: string | { name: string; description?: string; }; isDecorator?: boolean; } interface Root { (info: Type): Define, StateObject.From, PD.Normalize

>; } interface Define { (def: DefinitionBase): Transformer; } function build(namespace: string): Root; } function build(namespace: string): Builder.Root; const ROOT: Transformer; }