Skip to content

Commit

Permalink
Fixed an issue that caused inline actors with IDs being marked as not…
Browse files Browse the repository at this point in the history
… provided by typegen (#333)
  • Loading branch information
Andarist authored Apr 29, 2023
1 parent 87bf22a commit 2823e81
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 11 deletions.
6 changes: 6 additions & 0 deletions .changeset/red-brooms-rest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@xstate/tools-shared': patch
'stately-vscode': patch
---

Fixed an issue that caused inline actors with IDs being marked as not provided by typegen. This could result in false positive "Some implementations missing" error.
11 changes: 11 additions & 0 deletions packages/shared/src/__tests__/__examples__/inline-actor-with-id.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { createMachine } from 'xstate';

const someActor = () => Promise.resolve();

createMachine({
tsTypes: {} as import('./inline-actor-with-id.typegen').Typegen0,
invoke: {
id: 'someActor',
src: someActor,
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -1047,6 +1047,33 @@ export interface Typegen0 {
"
`;

exports[`getTypegenOutput inline-actor-with-id 1`] = `
"// This file was automatically generated. Edits will be overwritten
export interface Typegen0 {
"@@xstate/typegen": true;
internalEvents: {
"xstate.init": { type: "xstate.init" };
};
invokeSrcNameMap: {};
missingImplementations: {
actions: never;
delays: never;
guards: never;
services: never;
};
eventsCausingActions: {};
eventsCausingDelays: {};
eventsCausingGuards: {};
eventsCausingServices: {
someActor: "xstate.init";
};
matchesStates: undefined;
tags: never;
}
"
`;

exports[`getTypegenOutput inline-guard-function-expression 1`] = `
"// This file was automatically generated. Edits will be overwritten
Expand Down
23 changes: 16 additions & 7 deletions packages/shared/src/getTypegenData.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { MachineExtractResult } from '@xstate/machine-extractor';
import { createIntrospectableMachine } from './createIntrospectableMachine';
import { introspectMachine } from './introspectMachine';
import { IntrospectResult, introspectMachine } from './introspectMachine';
import { TypegenOptions } from './types';

export interface TypegenData extends ReturnType<typeof getTypegenData> {}
Expand All @@ -20,7 +20,10 @@ export const getTypegenData = (
);
const tsTypes = machineResult.machineCallResult.definition?.tsTypes?.node!;

const providedImplementations = getProvidedImplementations(machineResult);
const providedImplementations = getProvidedImplementations(
machineResult,
introspectResult,
);

const actions = introspectResult.actions.lines.filter(
(line) => !line.name.startsWith('xstate.'),
Expand Down Expand Up @@ -130,7 +133,10 @@ export const getTypegenData = (
};
};

const getProvidedImplementations = (machine: MachineExtractResult) => {
const getProvidedImplementations = (
machine: MachineExtractResult,
introspectResult: IntrospectResult,
) => {
return {
actions: new Set(
machine.machineCallResult.options?.actions?.properties.map(
Expand All @@ -147,11 +153,14 @@ const getProvidedImplementations = (machine: MachineExtractResult) => {
(property) => property.key,
) || [],
),
services: new Set(
machine.machineCallResult.options?.services?.properties.map(
services: new Set([
...introspectResult.services.lines
.filter(({ required }) => !required)
.map(({ name }) => name),
...(machine.machineCallResult.options?.services?.properties.map(
(property) => property.key,
) || [],
),
) || []),
]),
};
};

Expand Down
10 changes: 6 additions & 4 deletions packages/shared/src/introspectMachine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,16 +353,16 @@ function createTraversalContext(machine: AnyStateNode) {
nodeIdToSourceEventsMap: new Map<string, Set<string>>(),

actions: new ItemMap({
checkIfOptional: (name) => Boolean(machine.options?.actions?.[name]),
checkIfOptional: (name) => !!machine.options?.actions?.[name],
}),
delays: new ItemMap({
checkIfOptional: (name) => Boolean(machine.options?.delays?.[name]),
checkIfOptional: (name) => !!machine.options?.delays?.[name],
}),
guards: new ItemMap({
checkIfOptional: (name) => Boolean(machine.options?.guards?.[name]),
checkIfOptional: (name) => !!machine.options?.guards?.[name],
}),
services: new ItemMap({
checkIfOptional: (name) => Boolean(machine.options?.services?.[name]),
checkIfOptional: (name) => !!machine.options?.services?.[name],
}),
};
}
Expand Down Expand Up @@ -509,6 +509,8 @@ export const introspectMachine = (machine: AnyStateNode) => {
};
};

export type IntrospectResult = ReturnType<typeof introspectMachine>;

const getServiceSrc = (invoke: InvokeDefinition<any, any>) => {
if (typeof invoke.src === 'string') {
return invoke.src;
Expand Down

0 comments on commit 2823e81

Please sign in to comment.