Giter Club home page Giter Club logo

Comments (5)

Shtruk avatar Shtruk commented on May 28, 2024 6

@chlbri , @chrisjpatty

I've created some generic types for config and constants I use a lot. I'm not sure about some types (I've marked them), also there is no engine types. I plan to create PR when I finish.

declare module 'flume' {
  export namespace Colors {
    const yellow: string
    const orange: string
    const red: string
    const pink: string
    const purple: string
    const blue: string
    const green: string
    const grey: string
  }

  type ControlType = 'text' | 'number' | 'checkbox' | 'select' | 'multiselect' | 'custom'

  type ControlSetValueFn<V> = (newData: V, oldData: V) => V

  type CustomControlRenderFn<V> = <C = Object, I = Object>(
    data: V,
    onChange: (data: V) => void,
    context: C,
    redraw: () => void, // TODO: type
    portProps: PortProps<V>,
    inputData: I,
  ) => JSX.Element

  export interface SelectControlOption {
    value: string
    label?: string
    description?: string
  }

  interface Control<V> {
    type: ControlType
    label: string
    name: string
    setValue?: ControlSetValueFn<V>
  }

  interface TextControl extends Control {
    type: 'text'
    placeholder?: string // FixMe doesnt work for now
    defaultValue: string
  }

  interface NumberControl extends Control {
    type: 'number'
    defaultValue: number
    step?: number
  }

  interface CheckboxControl extends Control {
    type: 'checkbox'
    defaultValue: boolean
  }

  interface SelectControl extends Control {
    type: 'select'
    getOptions?: () => void // TODO: type
    placeholder?: string
    options: SelectControlOption[]
    defaultValue: string
  }

  interface MultiSelectControl extends Control {
    type: 'multiselect'
    getOptions?: () => void // TODO: type
    placeholder?: string
    options: SelectControlOption[]
    defaultValue: string[]
  }

  interface CustomControl<V> extends Control {
    type: 'custom'
    defaultValue: V
    render: CustomControlRenderFn<V>
  }

  export interface ControlConfig<V> {
    name: string
    label: string
    setValue?: ControlSetValueFn<V>
  }

  export interface TextControlConfig extends ControlConfig<string> {
    placeholder?: string // FixMe doesnt work for now
    defaultValue?: string
  }

  export interface NumberControlConfig extends ControlConfig<number> {
    step?: number
    defaultValue?: number
  }

  export interface CheckboxControlConfig extends ControlConfig<boolean> {
    defaultValue?: boolean
  }

  export interface SelectControlConfig extends ControlConfig<string> {
    options: SelectControlOption[]
    defaultValue?: string
  }

  export interface MultiSelectControlConfig extends ControlConfig<string[]> {
    options: SelectControlOption[]
    defaultValue?: string[]
  }

  export interface CustomControlConfig<V> extends ControlConfig<V> {
    render: CustomControlRenderFn<V>
  }

  export namespace Controls {
    function text (config: TextControlConfig): TextControl
    function select (config: SelectControlConfig): SelectControl
    function number (config: NumberControlConfig): NumberControl
    function checkbox (config: CheckboxControlConfig): CheckboxControl
    function multiselect (config: MultiSelectControlConfig): MultiSelectControl
    function custom <V> (config: CustomControlConfig<V>): CustomControl
  }

  interface PortProps<V> {
    label: string
    inputLabel: string
    name: string
    portName: string
    defaultValue: V
    inputData: V
  }

  interface PortConfig<P> {
    type: P
    name: string
    label: string
    color?: string
    acceptTypes?: P[]
    hidePort?: boolean
    controls?: Control[]
  }

  interface Port {
    // ForInternalUse
  }

  type GetPortsFn<P> = (ports: Record<P, (port?: Partial<PortConfig<P>>) => Port>) => Port

  export interface NodeConfig<N, P> {
    type: N
    label: string
    description?: string
    initialWidth?: number
    sortIndex?: number
    addable?: boolean
    deletable?: boolean
    root?: boolean
    inputs?: GetPortsFn<P>
    noControls?: boolean
    outputs?: GetPortsFn<P>
  }


  export interface FlumePlainConfig<P, N> {
    nodeTypes: Record<N, NodeConfig>
    portTypes: Record<P, PortConfig>
  }

  export class FlumeConfig<P = keyof {}, N = keyof {}> implements FlumePlainConfig<P, N> {
    constructor (config?: FlumePlainConfig<P, N>);
    nodeTypes: Record<N, NodeConfig<N, P>>
    portTypes: Record<P, PortConfig<P>>
    addRootNodeType (config: NodeConfig<N, P>): this;
    addNodeType (config: NodeConfig<N, P>): this;
    removeNodeType (type: N): this
    addPortType (config: PortConfig<P>): this;
    removePortType (type: P, { skipDynamicNodesCheck }?: { skipDynamicNodesCheck?: boolean }): this;
  }

  interface NodeEditorConfigProps {
    comments?: any;
    nodes?: any;
    nodeTypes?: Object
    portTypes?: Object
    defaultNodes?: any[]
    context?: Object
    onChange?: any;
    onCommentsChange?: any;
    initialScale?: any;
    spaceToPan?: boolean
    hideComments?: boolean
    disableComments?: boolean
    disableZoom?: boolean
    disablePan?: boolean
    circularBehavior?: any;
    debug?: any;
  }

  export function NodeEditor (params: NodeEditorConfigProps): JSX.Element
}

@chlbri u can use them as

export enum PortType {
  string = 'string',
  number = 'number'
}

export enum NodeType {
  stringConstant = 'stringConstant',
  numberConstant = 'numberConstant',
  concat = 'contact',
}

const config = new FlumeConfig<PortType, NodeType>()

config
  .addPortType({
    type: PortType.string,
    name: PortType.string,
    label: 'String',
    color: Colors.green,
    controls: [
      Controls.text({
        name: PortType.string,
        label: 'String',
      }),
    ],
  })
  .addPortType({
    type: PortType.number,
    name: PortType.number,
    label: 'Number',
    color: Colors.blue,
    acceptTypes: [PortType.number, PortType.string],
    controls: [
      Controls.number({
        name: PortType.number,
        label: 'Number',
      }),
    ],
  })
  .addNodeType({
    type: NodeType.stringConstant,
    label: 'String Constant',
    description: 'Defined string constant',
    inputs: (ports) => [
      ports.string({ label: 'String', hidePort: true }),
    ],
    outputs: (ports) => [
      ports.string(),
    ],
  })
  .addNodeType({
    type: NodeType.numberConstant,
    label: 'Number Constant',
    description: 'Defined number constant',
    inputs: (ports) => [
      ports.number({ label: 'Number', hidePort: true }),
    ],
    outputs: (ports) => [
      ports.number(),
    ],
  })
  .addNodeType({
    type: NodeType.concat,
    label: 'Concat',
    description: 'Concat number and string',
    inputs: (ports) => [
      ports.string(),
      ports.number(),
    ],
    outputs: (ports) => [
      ports.string(),
    ],
  })

OR

type PortType = 'string' | 'number'
type NodeType = 'stringConstant' | 'numberConstant' | 'concat'

const config = new FlumeConfig<PortType, NodeType>()

config
  .addPortType({
    type: 'string',
    name: 'string',
    label: 'String',
    color: Colors.green,
    controls: [
      Controls.text({
        name: 'string',
        label: 'String',
      }),
    ],
  })
  .addPortType({
    type: 'number',
    name: 'number',
    label: 'Number',
    color: Colors.blue,
    acceptTypes: ['string', 'number'],
    controls: [
      Controls.number({
        name: 'number',
        label: 'Number',
      }),
    ],
  })
  .addNodeType({
    type: 'stringConstant',
    label: 'String Constant',
    description: 'Defined string constant',
    inputs: (ports) => [
      ports.string({ label: 'String', hidePort: true }),
    ],
    outputs: (ports) => [
      ports.string(),
    ],
  })
  .addNodeType({
    type: 'numberConstant',
    label: 'Number Constant',
    description: 'Defined number constant',
    inputs: (ports) => [
      ports.number({ label: 'Number', hidePort: true }),
    ],
    outputs: (ports) => [
      ports.number(),
    ],
  })
  .addNodeType({
    type: 'concat',
    label: 'Concat',
    description: 'Concat number and string',
    inputs: (ports) => [
      ports.string(),
      ports.number(),
    ],
    outputs: (ports) => [
      ports.string(),
    ],
  })

Node types and port types, also arg of inputs/outputs fn in addNodeType will be typed by generic arg in FlumeConfig

from flume.

chrisjpatty avatar chrisjpatty commented on May 28, 2024 2

The first beta release with typescript support has been released. There's a couple problems with the public-facing API that I'm getting fixed asap, but wanted to drop a note in here in case anyone wants to try it out. https://github.com/chrisjpatty/flume/releases/tag/v1.0.0-0

from flume.

chlbri avatar chlbri commented on May 28, 2024

Great thanks!!!

from flume.

wlievens avatar wlievens commented on May 28, 2024

I've tried these declarations, but they don't seem to support ref on the NodeEditor...

from flume.

percentcer avatar percentcer commented on May 28, 2024

The first beta release with typescript support has been released. There's a couple problems with the public-facing API that I'm getting fixed asap, but wanted to drop a note in here in case anyone wants to try it out. https://github.com/chrisjpatty/flume/releases/tag/v1.0.0-0

Hey Chris, thanks for all your hard work on the TypeScript upgrade. I've been taking it for a spin and I'm getting these errors when trying to add generated controls (Controls.text, e.g.) to a port:

Type '{ type: "text" | "select" | "checkbox" | "multiselect" | "custom" | undefined; label: any; name: any; defaultValue: any; setValue: any; }' is not assignable to type 'Control'.
  Type '{ type: "text" | "select" | "checkbox" | "multiselect" | "custom" | undefined; label: any; name: any; defaultValue: any; setValue: any; }' is not assignable to type '{ type: ControlTypes; label: string; name: string; defaultValue: any; setValue: ValueSetter; } & CustomControl'.
    Type '{ type: "text" | "select" | "checkbox" | "multiselect" | "custom" | undefined; label: any; name: any; defaultValue: any; setValue: any; }' is not assignable to type '{ type: ControlTypes; label: string; name: string; defaultValue: any; setValue: ValueSetter; }'.
      Types of property 'type' are incompatible.
        Type '"text" | "select" | "checkbox" | "multiselect" | "custom" | undefined' is not assignable to type 'ControlTypes'.
          Type 'undefined' is not assignable to type 'ControlTypes'.ts(2322)

is this something on my end or have you seen anything similar?

My code snippet below:

config.addPortType({
    type: "asset",
    name: "asset",
    label: "Asset",
    color: Colors.red,
    controls: [
        Controls.text({label: "Asset Path", name: "path"}),
        Controls.number({label: "Asset ID", name: "id"}),
    ]
});

from flume.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.