Skip to content
Snippets Groups Projects
Select Git revision
  • rednatco-v2
  • master default protected
  • rednatco
  • test
  • ntc-tube-uniform-color
  • ntc-tube-missing-atoms
  • restore-vertex-array-per-program
  • watlas2
  • dnatco_new
  • cleanup-old-nodejs
  • webmmb
  • fix_auth_seq_id
  • update_deps
  • ext_dev
  • ntc_balls
  • nci-2
  • plugin
  • bugfix-0.4.5
  • nci
  • servers
  • v0.5.0-dev.1
  • v0.4.5
  • v0.4.4
  • v0.4.3
  • v0.4.2
  • v0.4.1
  • v0.4.0
  • v0.3.12
  • v0.3.11
  • v0.3.10
  • v0.3.9
  • v0.3.8
  • v0.3.7
  • v0.3.6
  • v0.3.5
  • v0.3.4
  • v0.3.3
  • v0.3.2
  • v0.3.1
  • v0.3.0
40 results

action.ts

Blame
  • action.ts 4.89 KiB
    /**
     * 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>
    }
    
    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<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
            };
            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 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> {
                <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;
    }