import { ShapeDefinition , MutationVector , ImageDefinition , ControlDefinition , ShapeMutationVector , ColorMutationVector , } from "./types" ; export type Visitor = ( item : ShapeDefinition | MutationVector | ControlDefinition , parents : ( ShapeDefinition | MutationVector ) [ ] ) => ShapeDefinition | MutationVector | ControlDefinition | false | undefined ; interface ItemWithType { type : string ; } export const isShapeDefinition = ( item ) : item is ShapeDefinition => item . type === "folder" || item . type === "sprite" ; export const isControlDefinition = ( item ) : item is ControlDefinition => item . type === "slider" ; export const isMutationVector = ( item ) : item is MutationVector => isShapeMutationVector ( item ) || isColorMutationVector ( item ) ; export const isShapeMutationVector = ( item ) : item is ShapeMutationVector => item . type === "deform" || item . type === "rotate" || item . type === "translate" || item . type === "stretch" || item . type === "opacity" ; export const isColorMutationVector = ( item ) : item is ColorMutationVector => item . type === "colorize" || item . type === "lightness" || item . type === "saturation" ; export const visitVectors = ( vectors , visitor , parents = [ ] ) : MutationVector [ ] => vectors . reduce ( ( result , item ) => { const visited = visitor ( item , parents ) ; if ( visited === false ) { return result ; } const newNode = ( visited && ! isMutationVector ( visited ) ) || visited === undefined ? item : visited ; return result . concat ( newNode ) ; } , [ ] as MutationVector [ ] ) ; export const visitShapes = ( shapes , visitor , parents = [ ] ) : ShapeDefinition [ ] => shapes . reduce ( ( result , item ) => { const visited = visitor ( item , parents ) ; if ( visited === false ) { return result ; } const newNode = ( visited && ! isShapeDefinition ( visited ) ) || visited === undefined ? item : visited ; const updatedChildSprites = newNode . type === "folder" ? { ... newNode , mutationVectors : visitVectors ( newNode . mutationVectors , visitor , parents . concat ( newNode ) ) , items : visitShapes ( newNode . items , visitor , parents . concat ( newNode ) ) , } : { ... newNode , mutationVectors : visitVectors ( newNode . mutationVectors , visitor , parents . concat ( newNode ) ) , } ; return result . concat ( updatedChildSprites ) ; } , [ ] as ShapeDefinition [ ] ) ; export const visitControls = ( controls , visitor ) : ControlDefinition [ ] => controls . reduce ( ( result , item ) => { const visited = visitor ( item , [ ] ) ; if ( visited === false ) { return result ; } const newNode = ( visited && ! isControlDefinition ( visited ) ) || visited === undefined ? item : visited ; return result . concat ( newNode ) ; } , [ ] as ControlDefinition [ ] ) ; export const visit = ( imageDefinition , visitor ) : ImageDefinition => { return { ... imageDefinition , shapes : visitShapes ( imageDefinition . shapes , visitor ) , controls : visitControls ( imageDefinition . controls , visitor ) , } ; } ;