@typeonce/effect-machine 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +64 -24
  2. package/dist/Machine.d.ts +386 -304
  3. package/dist/Machine.d.ts.map +1 -1
  4. package/dist/Machine.js +66 -171
  5. package/dist/Machine.js.map +1 -1
  6. package/dist/internal/machine/activities.d.ts +5 -12
  7. package/dist/internal/machine/activities.d.ts.map +1 -1
  8. package/dist/internal/machine/activities.js +47 -17
  9. package/dist/internal/machine/activities.js.map +1 -1
  10. package/dist/internal/machine/atom.d.ts +2 -2
  11. package/dist/internal/machine/atom.d.ts.map +1 -1
  12. package/dist/internal/machine/executionPlan.d.ts.map +1 -1
  13. package/dist/internal/machine/executionPlan.js +25 -0
  14. package/dist/internal/machine/executionPlan.js.map +1 -1
  15. package/dist/internal/machine/invocation.d.ts +10 -2
  16. package/dist/internal/machine/invocation.d.ts.map +1 -1
  17. package/dist/internal/machine/invocation.js +93 -34
  18. package/dist/internal/machine/invocation.js.map +1 -1
  19. package/dist/internal/machine/invocationEvent.d.ts +39 -0
  20. package/dist/internal/machine/invocationEvent.d.ts.map +1 -0
  21. package/dist/internal/machine/invocationEvent.js +43 -0
  22. package/dist/internal/machine/invocationEvent.js.map +1 -0
  23. package/dist/internal/machine/machine.d.ts +6 -50
  24. package/dist/internal/machine/machine.d.ts.map +1 -1
  25. package/dist/internal/machine/machine.js +8 -65
  26. package/dist/internal/machine/machine.js.map +1 -1
  27. package/dist/internal/machine/planner.d.ts +2 -1
  28. package/dist/internal/machine/planner.d.ts.map +1 -1
  29. package/dist/internal/machine/planner.js +45 -2
  30. package/dist/internal/machine/planner.js.map +1 -1
  31. package/dist/internal/machine/protocol.d.ts +9 -0
  32. package/dist/internal/machine/protocol.d.ts.map +1 -1
  33. package/dist/internal/machine/protocol.js +114 -0
  34. package/dist/internal/machine/protocol.js.map +1 -1
  35. package/dist/internal/machine/symbols.d.ts +2 -0
  36. package/dist/internal/machine/symbols.d.ts.map +1 -1
  37. package/dist/internal/machine/symbols.js +2 -0
  38. package/dist/internal/machine/symbols.js.map +1 -1
  39. package/dist/internal/machine/topology.d.ts.map +1 -1
  40. package/dist/internal/machine/topology.js +23 -0
  41. package/dist/internal/machine/topology.js.map +1 -1
  42. package/dist/unstable/reactivity/AtomMachine.d.ts +3 -3
  43. package/dist/unstable/reactivity/AtomMachine.d.ts.map +1 -1
  44. package/docs/agent-guide.md +118 -93
  45. package/package.json +2 -2
  46. package/src/Machine.ts +1040 -651
  47. package/src/internal/machine/activities.ts +48 -33
  48. package/src/internal/machine/atom.ts +3 -3
  49. package/src/internal/machine/executionPlan.ts +29 -0
  50. package/src/internal/machine/invocation.ts +179 -48
  51. package/src/internal/machine/invocationEvent.ts +72 -0
  52. package/src/internal/machine/machine.ts +20 -346
  53. package/src/internal/machine/planner.ts +61 -10
  54. package/src/internal/machine/protocol.ts +149 -0
  55. package/src/internal/machine/symbols.ts +3 -0
  56. package/src/internal/machine/topology.ts +23 -0
  57. package/src/unstable/reactivity/AtomMachine.ts +3 -3
@@ -1,4 +1,3 @@
1
- import * as Duration from "effect/Duration"
2
1
  import * as Effect from "effect/Effect"
3
2
  import * as Inspectable from "effect/Inspectable"
4
3
  import * as Option from "effect/Option"
@@ -34,6 +33,7 @@ import type { EnsureExecutable } from "./readiness.js"
34
33
  import * as internalRuntime from "./runtime.js"
35
34
  import * as Serialization from "./serialization.js"
36
35
  import * as StateDefinition from "./stateDefinition.js"
36
+ import { ChildMachineLogicTypeId } from "./symbols.js"
37
37
  import * as Topology from "./topology.js"
38
38
 
39
39
  export {
@@ -45,13 +45,12 @@ export {
45
45
  StartupError,
46
46
  StoppedError
47
47
  } from "./errors.js"
48
- export { InitialEventTypeId } from "./symbols.js"
48
+ export { ChildMachineLogicTypeId, InitialEventTypeId } from "./symbols.js"
49
49
 
50
50
  const TypeId = "~effect/Machine"
51
51
  export const SnapshotBuilderStateTypeId: unique symbol = Symbol("effect/Machine/SnapshotBuilderState")
52
52
  export const InvokeTypeId: unique symbol = Symbol.for("effect/Machine/Invoke")
53
53
  const ChildMachineTypeId = "~effect/Machine/ChildMachine"
54
- type InvokeLifecycleId = string
55
54
  type IsAny<A> = 0 extends 1 & A ? true : false
56
55
  type MachineRuntimeRequirement = internalRuntime.MachineRuntime
57
56
  type ExcludeCompatibleRuntime<Requirements, Events, Emits> = Requirements extends Runtime.Requirement<
@@ -883,6 +882,16 @@ export const event = <
883
882
  ...args: EventConstructorArgs<EventSchema>
884
883
  ): EventSchema["Type"] => Protocol.makeEvent(machine, schema, args.length === 0 ? {} : args[0])
885
884
 
885
+ export const events = <M extends Machine.Any>(
886
+ machine: M
887
+ ): Machine.EventConstructors<Machine.InputEvents<M>> =>
888
+ Protocol.eventConstructors(machine.events) as Machine.EventConstructors<Machine.InputEvents<M>>
889
+
890
+ export const internalEvents = <M extends Machine.Any>(
891
+ machine: M
892
+ ): Machine.EventConstructors<Machine.InternalEvents<M>> =>
893
+ Protocol.eventConstructors(machine.internalEvents) as Machine.EventConstructors<Machine.InternalEvents<M>>
894
+
886
895
  export const encodeSnapshot: <
887
896
  const States extends Machine.StateSchemas,
888
897
  const Events extends ReadonlyArray<Machine.TaggedSchema>,
@@ -957,145 +966,6 @@ export const decodeSnapshot: <
957
966
  Machine.SnapshotDecodingServices<States>
958
967
  > = Serialization.decodeSnapshot as any
959
968
 
960
- export const invoke = <
961
- ChildState,
962
- ChildEvent,
963
- ChildError = never,
964
- ChildRequirements = never,
965
- ChildOutput = never,
966
- ChildInitialError = never,
967
- Event = never,
968
- Address extends ChildAddress<never> | undefined = undefined
969
- >(
970
- config:
971
- & {
972
- readonly id: InvokeLifecycleId
973
- readonly src: () => Logic<
974
- ChildState,
975
- ChildEvent,
976
- ChildError,
977
- ChildRequirements,
978
- ChildOutput,
979
- ChildInitialError
980
- >
981
- readonly snapshot?: (
982
- context: Machine.InvokeSnapshotContext<ChildState, ChildError, ChildOutput>
983
- ) => Event | undefined
984
- }
985
- & ([Address] extends [undefined] ? {
986
- readonly address?: never
987
- }
988
- : {
989
- readonly address: Exclude<Address, undefined>
990
- } & ChildAddress.Compatibility<Exclude<Address, undefined>, NoInfer<ChildEvent>>)
991
- ): Machine.InvokeConfig<
992
- any,
993
- any,
994
- any,
995
- any,
996
- Event,
997
- ChildState,
998
- ChildEvent,
999
- ChildError,
1000
- ChildRequirements,
1001
- ChildOutput,
1002
- ChildInitialError
1003
- > => ({
1004
- ...config,
1005
- [InvokeTypeId]: undefined as any,
1006
- [Activities.ActivityMetadataTypeId]: { type: "process" }
1007
- })
1008
-
1009
- type InvokeEffectResult<Requirements, Event> = Machine.InvokeConfig<
1010
- any,
1011
- any,
1012
- any,
1013
- any,
1014
- never,
1015
- void,
1016
- never,
1017
- never,
1018
- Requirements,
1019
- Event | void,
1020
- never
1021
- >
1022
-
1023
- type InvokeEffectIsInfallible<Fx extends Effect.Effect<any, any, any>> = IsAny<Effect.Error<Fx>> extends true ? false
1024
- : [Effect.Error<Fx>] extends [never] ? true
1025
- : false
1026
-
1027
- type InvokeEffectConfig<
1028
- Fx extends Effect.Effect<any, any, any>,
1029
- SuccessEvent,
1030
- FailureEvent
1031
- > =
1032
- & {
1033
- readonly id: InvokeLifecycleId
1034
- readonly effect: Fx
1035
- readonly onSuccess: (value: NoInfer<Effect.Success<Fx>>) => SuccessEvent | void
1036
- }
1037
- & (
1038
- InvokeEffectIsInfallible<Fx> extends true ? {
1039
- readonly onFailure?: never
1040
- }
1041
- : {
1042
- readonly onFailure: (error: NoInfer<Effect.Error<Fx>>) => FailureEvent | void
1043
- }
1044
- )
1045
-
1046
- export const invokeEffect = <
1047
- const Fx extends Effect.Effect<any, any, any>,
1048
- SuccessEvent,
1049
- FailureEvent = never
1050
- >(
1051
- config: InvokeEffectConfig<Fx, SuccessEvent, FailureEvent>
1052
- ): InvokeEffectResult<
1053
- Effect.Services<Fx>,
1054
- SuccessEvent | (InvokeEffectIsInfallible<Fx> extends true ? never : FailureEvent)
1055
- > =>
1056
- ((config: {
1057
- readonly id: string
1058
- readonly effect: Effect.Effect<unknown, unknown, unknown>
1059
- readonly onSuccess: (value: unknown) => unknown
1060
- readonly onFailure?: (error: unknown) => unknown
1061
- }) => ({
1062
- ...invoke({
1063
- id: config.id,
1064
- src: () =>
1065
- effect(
1066
- config.onFailure === undefined
1067
- ? Effect.map(config.effect, config.onSuccess)
1068
- : Effect.matchEffect(config.effect, {
1069
- onFailure: (error) => Effect.succeed(config.onFailure!(error)),
1070
- onSuccess: (value) => Effect.succeed(config.onSuccess(value))
1071
- })
1072
- )
1073
- }),
1074
- [Activities.ActivityMetadataTypeId]: {
1075
- type: "effect",
1076
- outcomes: {
1077
- success: "dynamic",
1078
- failure: config.onFailure === undefined ? "none" : "dynamic"
1079
- }
1080
- }
1081
- }))(config as any) as any
1082
-
1083
- export const after = <Event extends { readonly _tag: PropertyKey }>(
1084
- duration: Duration.Input,
1085
- event: Event,
1086
- options?: { readonly id?: InvokeLifecycleId }
1087
- ): InvokeEffectResult<never, Event> => ({
1088
- ...invoke({
1089
- id: options?.id ?? `Machine.after:${String(event._tag)}`,
1090
- src: () => effect(Effect.as(Effect.sleep(duration), event))
1091
- }),
1092
- [Activities.ActivityMetadataTypeId]: {
1093
- type: "timer",
1094
- duration: Duration.format(Duration.fromInputUnsafe(duration)),
1095
- event: String(event._tag)
1096
- }
1097
- })
1098
-
1099
969
  export const retag = (
1100
970
  target: Machine.TaggedSchema,
1101
971
  source: { readonly _tag: PropertyKey },
@@ -1104,199 +974,6 @@ export const retag = (
1104
974
  const { _tag: _, ...fields } = source
1105
975
  return target.make({ ...fields, ...((patch ?? {}) as object) } as never)
1106
976
  }
1107
-
1108
- type InvokeMachineInput<Input extends Schema.Top> = Input extends typeof Schema.Void ? {
1109
- readonly input?: never
1110
- }
1111
- : {
1112
- readonly input: Input["Type"]
1113
- }
1114
-
1115
- export const invokeMachine: {
1116
- <
1117
- const States extends Machine.StateSchemas,
1118
- const Events extends ReadonlyArray<Machine.TaggedSchema>,
1119
- const Emits extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
1120
- const Input extends Schema.Top = typeof Schema.Void,
1121
- UnhandledStates extends Machine.StateIdentifier<States> = Machine.StateIdentifier<States>,
1122
- E = never,
1123
- R = never,
1124
- InitialE = never,
1125
- InitialR = never,
1126
- FinalStates extends Machine.StateIdentifier<States> = never,
1127
- Output = never,
1128
- SnapshotEvent = never,
1129
- DoneEvent = never,
1130
- Id extends string = string,
1131
- OutputStates extends Machine.StateIdentifier<States> = never,
1132
- InputEvents extends ReadonlyArray<Machine.TaggedSchema> = Events
1133
- >(
1134
- config:
1135
- & {
1136
- readonly child: ChildMachine<
1137
- Id,
1138
- & Machine<
1139
- States,
1140
- Events,
1141
- Input,
1142
- UnhandledStates,
1143
- E,
1144
- R,
1145
- InitialE,
1146
- InitialR,
1147
- FinalStates,
1148
- Output,
1149
- Emits,
1150
- OutputStates,
1151
- InputEvents
1152
- >
1153
- & EnsureExecutable<States, UnhandledStates, OutputStates>
1154
- >
1155
- readonly snapshot?: (
1156
- context: Machine.InvokeSnapshotContext<
1157
- Machine.Snapshot<States>,
1158
- | E
1159
- | ActionError<R>
1160
- | InfiniteTransitionError
1161
- | MachineSchemaDecodeError
1162
- | StoppedError,
1163
- Output
1164
- >
1165
- ) => SnapshotEvent | undefined
1166
- readonly onDone: (context: Machine.InvokeDoneContext<Output>) => DoneEvent | undefined
1167
- }
1168
- & InvokeMachineInput<Input>
1169
- ): Machine.InvokeConfig<
1170
- any,
1171
- any,
1172
- any,
1173
- any,
1174
- SnapshotEvent,
1175
- Machine.Snapshot<States>,
1176
- Machine.EventOf<InputEvents>,
1177
- E | ActionError<R> | InfiniteTransitionError | MachineSchemaDecodeError | StoppedError,
1178
- ExcludeCompatibleRuntime<
1179
- Exclude<ExecutionServices<InitialR | R>, internalRuntime.MachineRuntime>,
1180
- Machine.EventOf<Events>,
1181
- Machine.EmitOf<Emits>
1182
- >,
1183
- Output,
1184
- | InitialE
1185
- | E
1186
- | ActionError<InitialR | R>
1187
- | InfiniteTransitionError
1188
- | MachineSchemaDecodeError
1189
- | StartupError
1190
- | StoppedError,
1191
- Machine.EmitOf<Emits>,
1192
- DoneEvent
1193
- >
1194
- <
1195
- const States extends Machine.StateSchemas,
1196
- const Events extends ReadonlyArray<Machine.TaggedSchema>,
1197
- const Emits extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
1198
- const Input extends Schema.Top = typeof Schema.Void,
1199
- UnhandledStates extends Machine.StateIdentifier<States> = Machine.StateIdentifier<States>,
1200
- E = never,
1201
- R = never,
1202
- InitialE = never,
1203
- InitialR = never,
1204
- FinalStates extends Machine.StateIdentifier<States> = never,
1205
- Output = never,
1206
- SnapshotEvent = never,
1207
- Id extends string = string,
1208
- OutputStates extends Machine.StateIdentifier<States> = never,
1209
- InputEvents extends ReadonlyArray<Machine.TaggedSchema> = Events
1210
- >(
1211
- config:
1212
- & {
1213
- readonly child: ChildMachine<
1214
- Id,
1215
- & Machine<
1216
- States,
1217
- Events,
1218
- Input,
1219
- UnhandledStates,
1220
- E,
1221
- R,
1222
- InitialE,
1223
- InitialR,
1224
- FinalStates,
1225
- Output,
1226
- Emits,
1227
- OutputStates,
1228
- InputEvents
1229
- >
1230
- & EnsureExecutable<States, UnhandledStates, OutputStates>
1231
- >
1232
- readonly snapshot?: (
1233
- context: Machine.InvokeSnapshotContext<
1234
- Machine.Snapshot<States>,
1235
- | E
1236
- | ActionError<R>
1237
- | InfiniteTransitionError
1238
- | MachineSchemaDecodeError
1239
- | StoppedError,
1240
- Output
1241
- >
1242
- ) => SnapshotEvent | undefined
1243
- readonly onDone?: never
1244
- }
1245
- & InvokeMachineInput<Input>
1246
- ): Machine.InvokeConfig<
1247
- any,
1248
- any,
1249
- any,
1250
- any,
1251
- SnapshotEvent,
1252
- Machine.Snapshot<States>,
1253
- Machine.EventOf<InputEvents>,
1254
- E | ActionError<R> | InfiniteTransitionError | MachineSchemaDecodeError | StoppedError,
1255
- ExcludeCompatibleRuntime<
1256
- Exclude<ExecutionServices<InitialR | R>, internalRuntime.MachineRuntime>,
1257
- Machine.EventOf<Events>,
1258
- Machine.EmitOf<Emits>
1259
- >,
1260
- Output,
1261
- | InitialE
1262
- | E
1263
- | ActionError<InitialR | R>
1264
- | InfiniteTransitionError
1265
- | MachineSchemaDecodeError
1266
- | StartupError
1267
- | StoppedError,
1268
- Machine.EmitOf<Emits>
1269
- >
1270
- } = ((config: {
1271
- readonly child: ChildMachine.Any
1272
- readonly input?: unknown
1273
- readonly snapshot?: (context: Machine.InvokeSnapshotContext<any, any, any>) => unknown
1274
- readonly onDone?: (context: Machine.InvokeDoneContext<any>) => unknown
1275
- }) => {
1276
- const machine = config.child.machine
1277
- // An invoke descriptor fixes both its machine and input. Compile its process
1278
- // logic once; all mutable execution state belongs to the process instance.
1279
- const logic = machine.input === undefined
1280
- ? (internalProcess.toProcessLogic as any)(machine)
1281
- : (internalProcess.toProcessLogic as any)(machine, config.input)
1282
- return {
1283
- id: config.child.id,
1284
- address: config.child.id,
1285
- descriptor: config.child,
1286
- src: () => logic,
1287
- snapshot: config.snapshot,
1288
- onDone: config.onDone,
1289
- [Activities.ActivityMetadataTypeId]: {
1290
- type: "machine",
1291
- child: {
1292
- id: config.child.id,
1293
- machineId: machine.id ?? null
1294
- }
1295
- },
1296
- [InvokeTypeId]: undefined as any
1297
- }
1298
- }) as any
1299
-
1300
977
  export const planInitial: <
1301
978
  const States extends Machine.StateSchemas,
1302
979
  const Events extends ReadonlyArray<Machine.TaggedSchema>,
@@ -1494,7 +1171,7 @@ export const plan: <
1494
1171
  >
1495
1172
  & EnsureExecutable<States, UnhandledStates, OutputStates>,
1496
1173
  state: Machine.Snapshot<States>,
1497
- event: Machine.EventOf<InputEvents>
1174
+ event: Machine.EventInputOf<InputEvents>
1498
1175
  ) => Effect.Effect<
1499
1176
  & {
1500
1177
  readonly next: Machine.Snapshot<States>
@@ -1532,13 +1209,6 @@ export const plan: <
1532
1209
  never
1533
1210
  > = internalPlanner.plan as any
1534
1211
 
1535
- export const effect = <Output, Error = never, Requirements = never>(
1536
- effect: Effect.Effect<Output, Error, Requirements>
1537
- ): Logic<void, never, Error, Requirements, Output> => ({
1538
- initial: () => Effect.void,
1539
- run: () => effect
1540
- })
1541
-
1542
1212
  export const logic = <
1543
1213
  State,
1544
1214
  Event = never,
@@ -1587,7 +1257,11 @@ export const child = <const Id extends string, M extends Machine.Any>(
1587
1257
  ): ChildMachine<Id, M> => ({
1588
1258
  [ChildMachineTypeId]: ChildMachineTypeId,
1589
1259
  id,
1590
- machine
1260
+ machine,
1261
+ [ChildMachineLogicTypeId]: (input) =>
1262
+ machine.input === undefined
1263
+ ? (internalProcess.toProcessLogic as any)(machine)
1264
+ : (internalProcess.toProcessLogic as any)(machine, input)
1591
1265
  })
1592
1266
 
1593
1267
  export const childAddress = <Event = never>(id: string): ChildAddress<Event> => id as ChildAddress<Event>
@@ -1703,7 +1377,7 @@ export const start: <
1703
1377
  ) => Effect.Effect<
1704
1378
  MachineRef<
1705
1379
  Machine.Snapshot<States>,
1706
- Machine.EventOf<InputEvents>,
1380
+ Machine.EventInputOf<InputEvents>,
1707
1381
  | E
1708
1382
  | ActionError<R>
1709
1383
  | InfiniteTransitionError
@@ -1761,7 +1435,7 @@ export const resume: <
1761
1435
  ) => Effect.Effect<
1762
1436
  MachineRef<
1763
1437
  Machine.Snapshot<States>,
1764
- Machine.EventOf<InputEvents>,
1438
+ Machine.EventInputOf<InputEvents>,
1765
1439
  | E
1766
1440
  | ActionError<R>
1767
1441
  | InfiniteTransitionError
@@ -38,6 +38,7 @@ import {
38
38
  validateInitialConfiguration
39
39
  } from "./configuration.js"
40
40
  import { InfiniteTransitionError, MachineSchemaDecodeError, StartupError } from "./errors.js"
41
+ import * as InvocationEvent from "./invocationEvent.js"
41
42
  import { decodeEventSync, decodeInputSync, decodeStateValueSync } from "./protocol.js"
42
43
  import { InitialEventTypeId } from "./symbols.js"
43
44
  import {
@@ -798,6 +799,54 @@ const selectEventTransitions = <
798
799
  return selected
799
800
  }
800
801
 
802
+ const selectInvocationTransition = <
803
+ const States extends Machine.StateSchemas,
804
+ const Events extends ReadonlyArray<Machine.TaggedSchema>,
805
+ const Emits extends ReadonlyArray<Machine.TaggedSchema>,
806
+ E,
807
+ R
808
+ >(
809
+ machine: Machine.Any,
810
+ configuration: ActiveConfiguration,
811
+ event: InvocationEvent.InvocationEvent
812
+ ): ReadonlyArray<SelectedTransition<States, E, R, any>> => {
813
+ if (!configuration.active.has(event.path)) return []
814
+ const config = machine.handlers[event.path] as Machine.AnyStateConfig | undefined
815
+ const invoke = InvocationEvent.definitions(config?.invoke).find((definition) => {
816
+ const id = "child" in definition ? definition.child?.id : definition.id
817
+ return String(id) === event.id
818
+ })
819
+ if (invoke === undefined) return []
820
+ const handler = event.type === "done"
821
+ ? invoke.onDone
822
+ : event.type === "failure"
823
+ ? invoke.onFailure
824
+ : invoke.onSnapshot
825
+ const transition = normalizeTransition(handler)
826
+ if (transition === undefined) return []
827
+ const snapshot = snapshotFromConfiguration<States>(machine, configuration)
828
+ const context = {
829
+ state: configuration.values.get(event.path),
830
+ parent: getParentValue(machine, configuration, event.path),
831
+ parents: getParentValues(machine, configuration, event.path),
832
+ snapshot,
833
+ target: getTargetBuilder(machine, event.path),
834
+ id: event.id,
835
+ ...(event.type === "done"
836
+ ? { output: event.output }
837
+ : event.type === "failure"
838
+ ? { error: event.error }
839
+ : { snapshot: event.snapshot })
840
+ }
841
+ return [{
842
+ sourcePath: event.path,
843
+ leafPath: getActiveLeafPathFrom(machine, configuration, event.path),
844
+ trigger: { type: "invoke", id: event.id, outcome: event.type },
845
+ transition: transition as unknown as MicrostepTransition<States, E, R, any>,
846
+ context
847
+ }]
848
+ }
849
+
801
850
  export const getTargetNodePath = <const States extends Machine.StateSchemas>(
802
851
  target:
803
852
  | Machine.Snapshot<States>
@@ -1812,11 +1861,11 @@ const macrostepConfiguration = <
1812
1861
  >(
1813
1862
  machine: Machine<States, Events, Input, UnhandledStates, E, R, InitialE, InitialR, FinalStates, Output, Emits>,
1814
1863
  configuration: ActiveConfiguration,
1815
- event: Machine.EventOf<Events>
1864
+ event: Machine.EventOf<Events> | InvocationEvent.InvocationEvent
1816
1865
  ) => {
1817
- const decodedEvent = decodeEventSync<Events>(machine, event)
1866
+ const decodedEvent = InvocationEvent.isInvocationEvent(event) ? event : decodeEventSync<Events>(machine, event)
1818
1867
  if (isActiveFinalConfiguration(machine, configuration)) {
1819
- const completed = completeConfigurationSync(machine, configuration, decodedEvent)
1868
+ const completed = completeConfigurationSync(machine, configuration, decodedEvent as any)
1820
1869
  const root = getRootPath(machine, completed.configuration)
1821
1870
  if (!completed.configuration.outputs.has(root)) {
1822
1871
  throw new Error("Machine reached a terminal configuration without a completed root output")
@@ -1831,11 +1880,13 @@ const macrostepConfiguration = <
1831
1880
  }
1832
1881
  }
1833
1882
 
1834
- const selections = selectEventTransitions<States, Events, Emits, E, R>(
1835
- machine,
1836
- configuration,
1837
- decodedEvent as Machine.EventByTag<Events, Machine.TagOf<Events[number]>>
1838
- )
1883
+ const selections = InvocationEvent.isInvocationEvent(decodedEvent)
1884
+ ? selectInvocationTransition<States, Events, Emits, E, R>(machine, configuration, decodedEvent)
1885
+ : selectEventTransitions<States, Events, Emits, E, R>(
1886
+ machine,
1887
+ configuration,
1888
+ decodedEvent as Machine.EventByTag<Events, Machine.TagOf<Events[number]>>
1889
+ )
1839
1890
  if (selections.length === 0) {
1840
1891
  return {
1841
1892
  next: configuration,
@@ -1849,14 +1900,14 @@ const macrostepConfiguration = <
1849
1900
  const step = microstep(
1850
1901
  machine,
1851
1902
  configuration,
1852
- decodedEvent,
1903
+ decodedEvent as any,
1853
1904
  selections
1854
1905
  )
1855
1906
  const commands = [...step.commands]
1856
1907
  const raisedEvents = [...step.raisedEvents]
1857
1908
  const emittedEvents = [...step.emittedEvents]
1858
1909
  const microsteps = [step]
1859
- return settle(machine, step.next, decodedEvent, commands, raisedEvents, emittedEvents, microsteps)
1910
+ return settle(machine, step.next, decodedEvent as any, commands, raisedEvents, emittedEvents, microsteps)
1860
1911
  }
1861
1912
 
1862
1913
  const snapshotMacrostep = <