message: wip, ShapeBuilder argument for ShapeRepresentation
diff: @@ -32,7 +32,14 @@ export interface ShapeRepresentation<D, G extends Geometry, P extends Geometry.P
  export type ShapeGetter<D, G extends Geometry, P extends Geometry.Params<G>> = (ctx: RuntimeContext, data: D, props: PD.Values<P>, shape?: Shape<G>) => Shape<G> | Promise<Shape<G>>
  -export function ShapeRepresentation<D, G extends Geometry, P extends Geometry.Params<G>>(getShape: ShapeGetter<D, G, P>, geometryUtils: GeometryUtils<G>): ShapeRepresentation<D, G, P> {
  +export interface ShapeBuilder<G extends Geometry, P extends Geometry.Params<G>> {
  + /** Hook to modify represetantion props */
  + modifyProps?: (props: Partial<PD.Values<P>>) => Partial<PD.Values<P>>
  + /** Hook to modify representation state */
  + modifyState?: (state: Partial<Representation.State>) => Partial<Representation.State>
  +}
  +
  +export function ShapeRepresentation<D, G extends Geometry, P extends Geometry.Params<G>>(getShape: ShapeGetter<D, G, P>, geometryUtils: GeometryUtils<G>, builder: ShapeBuilder<G, P> = {}): ShapeRepresentation<D, G, P> {
  let version = 0
  const updated = new Subject<number>()
  const _state = Representation.createState()
  @@ -45,6 +52,8 @@ export function ShapeRepresentation<D, G extends Geometry, P extends Geometry.Pa
  let currentParams: P
  let locationIt: LocationIterator
  + if (builder.modifyState) Representation.updateState(_state, builder.modifyState(_state))
  +
  const updateState = VisualUpdateState.create()
  function prepareUpdate(props: Partial<PD.Values<P>> = {}, shape?: Shape<G>) {
  @@ -82,6 +91,8 @@ export function ShapeRepresentation<D, G extends Geometry, P extends Geometry.Pa
  }
  function createOrUpdate(props: Partial<PD.Values<P>> = {}, data?: D) {
  + if (builder.modifyProps) props = builder.modifyProps(props)
  +
  return Task.create('ShapeRepresentation.create', async runtime => {
  const newProps = Object.assign(currentProps, props)
  const shape = data ? await getShape(runtime, data, newProps, _shape) : undefined
  @@ -100,6 +111,8 @@ export function ShapeRepresentation<D, G extends Geometry, P extends Geometry.Pa
  const transform = createShapeTransform(_shape.transforms)
  const values = geometryUtils.createValues(_shape.geometry, transform, locationIt, _theme, newProps)
  const state = geometryUtils.createRenderableState(newProps)
  + if (builder.modifyState) Object.assign(state, builder.modifyState(state))
  + Representation.updateState(_state, state)
  _renderObject = createRenderObject(_shape.geometry.kind, values, state, materialId)
  if (_renderObject) renderObjects.push(_renderObject) // add new renderObject to list
  @@ -178,6 +191,8 @@ export function ShapeRepresentation<D, G extends Geometry, P extends Geometry.Pa
  return Visual.mark(_renderObject, loci, action, lociApply)
  },
  setState(state: Partial<Representation.State>) {
  + if (builder.modifyState) state = builder.modifyState(state)
  +
  if (_renderObject) {
  if (state.visible !== undefined) Visual.setVisibility(_renderObject, state.visible)
  if (state.alphaFactor !== undefined) Visual.setAlphaFactor(_renderObject, state.alphaFactor)
  