UNPKG

molstar

Version:

A comprehensive macromolecular library.

164 lines (163 loc) 7.86 kB
/** * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author David Sehnal <david.sehnal@gmail.com> */ import { Task } from '../mol-task'; import { StateObject, StateObjectCell } from './object'; import { StateTransform } from './transform'; import { ParamDefinition as PD } from '../mol-util/param-definition'; import { StateAction } from './action'; import { StateTreeSpine } from './tree/spine'; export { Transformer as StateTransformer }; interface Transformer<A extends StateObject = StateObject, B extends StateObject = StateObject, P extends {} = any> { apply(parent: StateTransform.Ref, params?: P, props?: Partial<StateTransform.Options>): StateTransform<this>; toAction(): StateAction<A, void, P>; readonly namespace: string; readonly id: Transformer.Id; readonly definition: Transformer.Definition<A, B, P>; /** 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<any, any, any>> = T extends Transformer<any, any, infer P> ? P : unknown; type From<T extends Transformer<any, any, any>> = T extends Transformer<infer A, any, any> ? A : unknown; type To<T extends Transformer<any, any, any>> = T extends Transformer<any, infer B, any> ? B : unknown; type Cell<T extends Transformer<any, any, any>> = T extends Transformer<any, infer B, any> ? StateObjectCell<B> : unknown; function getParamDefinition<T extends Transformer>(t: T, a: From<T> | undefined, globalCtx: unknown): PD.For<Params<T>>; function is(obj: any): obj is Transformer; interface ApplyParams<A extends StateObject = StateObject, P extends {} = {}> { 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<unknown>; }; } interface UpdateParams<A extends StateObject = StateObject, B extends StateObject = StateObject, P extends {} = {}> { 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<unknown>; }; } interface AutoUpdateParams<A extends StateObject = StateObject, B extends StateObject = StateObject, P extends {} = {}> { a: A; b: B; oldParams: P; newParams: P; } interface DisposeParams<B extends StateObject = StateObject, P extends {} = {}> { 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<A extends StateObject = StateObject, B extends StateObject = StateObject, P extends {} = {}> { /** * 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<A, P>, globalCtx: unknown): Task<B> | 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<A, B, P>, globalCtx: unknown): Task<UpdateResult> | UpdateResult; /** Determine if the transformer can be applied automatically on UI change. Default is false. */ canAutoUpdate?(params: AutoUpdateParams<A, B, P>, 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<B, P>, globalCtx: unknown): void; /** Custom conversion to and from JSON */ readonly customSerialization?: { toJSON(params: P, obj?: B): any; fromJSON(data: any): P; }; } interface Definition<A extends StateObject = StateObject, B extends StateObject = StateObject, P extends {} = {}> extends DefinitionBase<A, B, P> { 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<any, any, any>[]; function get(id: string): Transformer; function fromType(type: StateObject.Type): ReadonlyArray<Transformer>; function create<A extends StateObject, B extends StateObject, P extends {} = {}>(namespace: string, definition: Definition<A, B, P>): Transformer<A, B, P>; function factory(namespace: string): <A extends StateObject<any, StateObject.Type<any>>, B extends StateObject<any, StateObject.Type<any>>, P extends {} = {}>(definition: Definition<A, B, P>) => Transformer<A, B, P>; function builderFactory(namespace: string): Builder.Root; namespace Builder { interface Type<A extends StateObject.Ctor, B extends StateObject.Ctor, P extends {}> { name: string; from: A | A[]; to: B | B[]; /** The source StateObject can be undefined: used for generating docs. */ params?: PD.For<P> | ((a: StateObject.From<A> | undefined, globalCtx: any) => PD.For<P>); display?: string | { name: string; description?: string; }; isDecorator?: boolean; } interface Root { <A extends StateObject.Ctor, B extends StateObject.Ctor, P extends {}>(info: Type<A, B, P>): Define<StateObject.From<A>, StateObject.From<B>, PD.Normalize<P>>; } interface Define<A extends StateObject, B extends StateObject, P> { (def: DefinitionBase<A, B, P>): Transformer<A, B, P>; } function build(namespace: string): Root; } function build(namespace: string): Builder.Root; const ROOT: Transformer<any, any, {}>; }