Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VSCode extension generates incorrect signature for invoked service with guards #275

Closed
viglucci opened this issue Dec 12, 2022 · 3 comments

Comments

@viglucci
Copy link

viglucci commented Dec 12, 2022

Description

The VScode extension generates an incorrect definition for a machine that uses a guarded transition for the invoke.done event from an invoked service.

Given the below machine, which was modeled with the vscode extension:

{
  initial: 'Processing Build Logs',
  states: {
    'Processing Build Logs': {
      invoke: {
        src: 'processBuildLog',
        id: 'processBuildLog',
        onDone: [{
          target: "Uploading Full Log File",
          cond: "hasWarningsOrErrors"
        }, "Done"],
        onError: [
          {
            target: "Failed to Parse Build Logs",
            actions: 'reportError',
          },
        ],
      },
    },

    "Upload Warnings Log to Slack": {
      invoke: {
        src: "uploadWarningsToSlack",
        id: "uploadWarningsToSlack",

        onError: [
          {
            target: "Failed to Upload Warning and Error Logs",
            actions: 'reportError',
          },
        ],
        onDone: "Done"
      }
    },

    'Failed to Upload Warning and Error Logs': {
      invoke: {
        src: 'notifyFailedToUploadLogsToSlack',
        id: 'notifyFailedToUploadLogsToSlack',
        onDone: [
          {
            target: '#Run Job Machine.Done',
          },
        ],
        onError: [
          {
            target: '#Run Job Machine.UnexpectedError',
          },
        ],
      },
    },

    'Failed to Parse Build Logs': {
      invoke: {
        src: 'notifyFailedToParseBuildLogs',
        id: 'notifyFailedToParseBuildLogs',
        onDone: [
          {
            target: '#Run Job Machine.Done',
          },
        ],
        onError: [
          {
            target: '#Run Job Machine.UnexpectedError',
          },
        ],
      },
    },

    "Uploading Full Log File": {
      invoke: {
        src: "uploadFullLogToSlack",
        id: "uploadFullLogToSlack",
        onDone: [{
          target: "Upload Warnings Log to Slack",
          cond: "logHasWarnings"
        }, {
          target: "Upload Errors to Slack",
          cond: "logHasErrors"
        }, "Done"],
        onError: {
          target: "Failed to Upload Warning and Error Logs",
          actions: "reportError"
        }
      }
    },

    "Upload Errors to Slack": {
      invoke: {
        src: "uploadErrorsToSlack",
        id: "uploadErrorsToSlack",
        onDone: "Done",
        onError: {
          target: "Failed to Upload Warning and Error Logs",
          actions: "reportError"
        }
      }
    }
  },

  Done: {
    type: "final"
  },
}

The following type error is given:

Type '{ src: string; id: string; onDone: (string | { target: string; cond: string; })[]; onError: { target: string; actions: string; }[]; }' is not assignable to type 'SingleOrArray<AnyStateMachine | InvokeConfig<{ message: any; job: any; jobKey: string; jobPath: string; queueLocation: string; jobReference: JenkinsJobReference; fullLog: GetProgressiveTextReturn; parsedErrorLogs: any[]; parsedWarningLogs: any[]; jobCompletedMessage: any; abortedByText: string; }, { ...; }>>'.
  Types of property 'onDone' are incompatible.
    Type '(string | { target: string; cond: string; })[]' is not assignable to type 'string | SingleOrArray<TransitionConfig<{ message: any; job: any; jobKey: string; jobPath: string; queueLocation: string; jobReference: JenkinsJobReference; fullLog: GetProgressiveTextReturn; parsedErrorLogs: any[]; parsedWarningLogs: any[]; jobCompletedMessage: any; abortedByText: string; }, DoneInvokeEvent<...>>>'.
      Type '(string | { target: string; cond: string; })[]' is not assignable to type 'TransitionConfig<{ message: any; job: any; jobKey: string; jobPath: string; queueLocation: string; jobReference: JenkinsJobReference; fullLog: GetProgressiveTextReturn; parsedErrorLogs: any[]; parsedWarningLogs: any[]; jobCompletedMessage: any; abortedByText: string; }, DoneInvokeEvent<...>>[]'.
        Type 'string | { target: string; cond: string; }' is not assignable to type 'TransitionConfig<{ message: any; job: any; jobKey: string; jobPath: string; queueLocation: string; jobReference: JenkinsJobReference; fullLog: GetProgressiveTextReturn; parsedErrorLogs: any[]; parsedWarningLogs: any[]; jobCompletedMessage: any; abortedByText: string; }, DoneInvokeEvent<...>>'.
          Type 'string' has no properties in common with type 'TransitionConfig<{ message: any; job: any; jobKey: string; jobPath: string; queueLocation: string; jobReference: JenkinsJobReference; fullLog: GetProgressiveTextReturn; parsedErrorLogs: any[]; parsedWarningLogs: any[]; jobCompletedMessage: any; abortedByText: string; }, DoneInvokeEvent<...>>'.ts(2322)
types.d.ts(335, 5): The expected type comes from property 'invoke' which is declared here on type 'StateNodeConfig<{ message: any; job: any; jobKey: string; jobPath: string; queueLocation: string; jobReference: JenkinsJobReference; fullLog: GetProgressiveTextReturn; parsedErrorLogs: any[]; parsedWarningLogs: any[]; jobCompletedMessage: any; abortedByText: string; }, any, { ...; }, BaseActionObject>'

Changing the "else" portion of the guarded transition manually from "Done" to { target: "Done"} resolves the issue.

[
  {
    target: "Uploading Full Log File",
    cond: "hasWarningsOrErrors"
  }, 
- "Done",
+ {
+   target: "Done"
+ }
]

Environment

XState VSCode version: v1.11.0
Xstate version: 4.32.1

@Andarist
Copy link
Member

I had to fix a couple of errors with the given config before I could see this error. When I did that I managed to minimize the repro case to just this:

import { createMachine } from "xstate";

createMachine({
  invoke: {
    src: () => () => {},
    onDone: [{ target: "a" }, "b"],
  },
});

It's a problem with XState types. Could you confirm that this is the same issue that you are observing?

@viglucci
Copy link
Author

viglucci commented Jan 4, 2023

Hey @Andarist ,

I had to expand the minimal reproduction out slightly to include the states to limit the errors only to those related to the service config, however I can confirm that this minimal repro does represent the issue I am encountering.

import { createMachine } from "xstate";

createMachine({
    invoke: {
        src: () => () => { },
        onDone: [{ target: "a" }, "b"],
    },
    states: {
        a: {},
        b: {},
    },
});

@Andarist
Copy link
Member

Andarist commented Feb 7, 2023

Closed by statelyai/xstate#3745

@Andarist Andarist closed this as completed Feb 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants