nocode-js / sequential-workflow-editor

Powerful workflow editor builder for any workflow designer.
https://nocode-js.com/
MIT License
80 stars 7 forks source link

Returning or passing variables between steps #34

Open zacherkkila opened 3 months ago

zacherkkila commented 3 months ago

I appreciate your work on this library, very cool!

Just so you know, I am not sure it makes a big difference, but I am using the React designer.

I have been trying to figure out the standard way to handle this rather than building a custom variable service of some sort.

Step A - Performs a computation and stores it to a variable Step B - Uses the variable/return from the previous step

It seems that the scope is limited to the step itself when the variable is defined within the step.

image

However, I need to use the result of Step A and feed that into Step B. It is not available here

image

From the docs

When a variable is defined in the parent scope, it can be accessed in the child scope, but not vice versa.

Is the "log" step in the image not a child of the "output" step? It seems they are more treated as independent functions rather than a parent/child relationship

What is the best way to handle this scenario? Essentially a return variable from one step and use that return variable in the next step.

Output Step

interface OuputStep extends Step {
  type: 'output'
  componentType: 'task'
  properties: {
    output: NullableVariableDefinition
    showVariable: NullableVariable
  }
}

export const Output = createStepModel<OuputStep>('output', 'task', (step) => {
  step.category('Output')
  step.label('Output')
  step.property('output').value(
    createNullableVariableDefinitionValueModel({
      valueType: 'number',
      isRequired: true,
      defaultValue: {
        name: 'test',
        type: 'number',
      },
    })
  )
  step
    .property('showVariable')
    .value(
      createNullableVariableValueModel({
        isRequired: true,
        valueType: 'number',
      })
    )
    .label('Value to Log')
})

Log Step

interface ValueLogStepDef extends Step {
  componentType: 'task'
  properties: {
    valueToLog: NullableVariable
    alert: boolean
  }
}

export const ValueLog = createStepModel<ValueLogStepDef>('log', 'task', (step) => {
  step.category('Tracing')

  step
    .property('valueToLog')
    .value(
      createNullableVariableValueModel({
        isRequired: true,
        valueType: 'number',
      })
    )
    .label('Value to Log')

  step.property('alert').value(createBooleanValueModel({})).label('Alert?')
})

Definition

  const definitionModel = useMemo(
    () =>
      createDefinitionModel<T>((model) => {
        model.valueTypes(['string', 'number'])
        model.root(rootModel)
        model.steps([OutputStep, ValueLogStep])
      }),
    []
  )

Thank you very much!

b4rtaz commented 3 months ago

Hello @zacherkkila!

Is the "log" step in the image not a child of the "output" step?

I think you understand differently the "child" term than the documentation describes (maybe the documentation is not too precise).

The child means a step inside a step, like:

|__ loop { defines x }
|   |_ setAddress { x = 127.0.0.1 }
|   |_ ping1 { use x } // OK
|
|_ ping2 { use x } // ERROR

In the above example ping1 has the access to the x variable defined by the loop step. The ping2 step DOES NOT have the access to the x variable. You can try to represent it using some abstract programming language:

section (x = null) {
   x = 127.0.0.1
   ping(x) // OK
}
ping(x) // ERROR

In the case from your example you can solve this problem by:

interface MyDefinition extends Definition {
   properties: {
      myVariables: VariableDefinitions;
   // ...
}

interface OuputStep extends Step {
   properties: {
      output: NullableVariable;
   // ...
}

interface ValueLogStep extends Step {
   properties: {
      valueToLog: NullableVariable;
   // ...
}

I reccomend to check the source code of this demo.


Another thing is that, I understand the need that some step may produce an output for a next step. This behaviour I noticed in Zapier. The Sequential Workflow Editor doesn't support this behaviour, but maybe this is something that is worth to consider for the pro version.

zacherkkila commented 3 months ago

Thank you for the response!

The Sequential Workflow Editor doesn't support this behaviour, but maybe this is something that is worth to consider for the pro version

I do think this would be a useful add.. Just to give an idea of the feature we are building:

Zapier is a good parallel here, though entirely different use case for us

Thank you for the recommendations, we should be able to make something work here with that info!