123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- /**
- * 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 { UUID } from '../mol-util';
- import { ParamDefinition as PD } from '../mol-util/param-definition';
- import { StateObject, StateObjectCell } from './object';
- import { State } from './state';
- import { StateTransformer } from './transformer';
- import { StateTransform } from './transform';
- export { StateAction };
- interface StateAction<A extends StateObject = StateObject, T = any, P extends {} = {}> {
- create(params: P): StateAction.Instance,
- readonly id: UUID,
- readonly definition: StateAction.Definition<A, T, P>,
- /** create a fresh copy of the params which can be edited in place */
- createDefaultParams(a: A, globalCtx: unknown): P
- }
- namespace StateAction {
- export type Id = string & { '@type': 'transformer-id' }
- export type Params<T extends StateAction<any, any, any>> = T extends StateAction<any, any, infer P> ? P : unknown;
- export type ReType<T extends StateAction<any, any, any>> = T extends StateAction<any, infer T, any> ? T : unknown;
- export type ControlsFor<Props> = { [P in keyof Props]?: PD.Any }
- export interface Instance {
- action: StateAction,
- params: any
- }
- export interface ApplyParams<A extends StateObject = StateObject, P extends {} = {}> {
- ref: string,
- cell: StateObjectCell,
- a: A,
- state: State,
- params: P
- }
- export interface DefinitionBase<A extends StateObject = StateObject, T = any, P extends {} = {}> {
- /**
- * Apply an action that modifies the State specified in Params.
- */
- run(params: ApplyParams<A, P>, globalCtx: unknown): T | Task<T>,
- /** Test if the transform can be applied to a given node */
- isApplicable?(a: A, aTransform: StateTransform<StateTransformer<any, A, any>>, globalCtx: unknown): boolean
- }
- export interface Definition<A extends StateObject = StateObject, T = any, P extends {} = {}> extends DefinitionBase<A, T, P> {
- readonly from: StateObject.Ctor[],
- readonly display: { readonly name: string, readonly description?: string },
- params?(a: A, globalCtx: unknown): { [K in keyof P]: PD.Any }
- }
- export function create<A extends StateObject, T, P extends {} = {}>(definition: Definition<A, T, P>): StateAction<A, T, P> {
- const action: StateAction<A, T, P> = {
- create(params) { return { action, params }; },
- id: UUID.create22(),
- definition,
- createDefaultParams(a, globalCtx) { return definition.params ? PD.getDefaultValues(definition.params(a, globalCtx)) : {} as any; }
- };
- return action;
- }
- export function fromTransformer<T extends StateTransformer>(transformer: T) {
- const def = transformer.definition;
- return create<StateTransformer.From<T>, void, StateTransformer.Params<T>>({
- from: def.from,
- display: def.display,
- params: def.params as StateTransformer.Definition<StateTransformer.From<T>, any, StateTransformer.Params<T>>['params'],
- isApplicable: transformer.definition.isApplicable
- ? (a, t, ctx) => transformer.definition.isApplicable!(a, ctx)
- : void 0,
- run({ cell, state, params }) {
- const tree = state.build().to(cell.transform.ref).apply(transformer, params);
- return state.updateTree(tree) as unknown as Task<void>;
- }
- });
- }
- export namespace Builder {
- export interface Type<A extends StateObject.Ctor, P extends {}> {
- from?: A | A[],
- params?: PD.For<P> | ((a: StateObject.From<A>, globalCtx: any) => PD.For<P>),
- display?: string | { name: string, description?: string },
- isApplicable?: DefinitionBase<StateObject.From<A>, any, P>['isApplicable']
- }
- export interface Root {
- <A extends StateObject.Ctor, P extends { }>(info: Type<A, P>): Define<StateObject.From<A>, PD.Normalize<P>>
- }
- export interface Define<A extends StateObject, P extends {}> {
- <T>(def: DefinitionBase<A, T, P> | DefinitionBase<A, T, P>['run']): StateAction<A, T, P>,
- }
- function root(info: Type<any, any>): Define<any, any> {
- return def => create({
- from: info.from instanceof Array
- ? info.from
- : !!info.from ? [info.from] : [],
- display: typeof info.display === 'string'
- ? { name: info.display }
- : !!info.display
- ? info.display
- : { name: 'Unnamed State Action' },
- params: typeof info.params === 'object'
- ? () => info.params as any
- : !!info.params
- ? info.params as any
- : void 0,
- isApplicable: info.isApplicable,
- ...(typeof def === 'function'
- ? { run: def }
- : def)
- });
- }
- export const build: Root = (info: any) => root(info);
- }
- export const build = Builder.build;
- }
|