aws-local-stepfunctions 0.7.0 → 1.1.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.
@@ -25,44 +25,35 @@ var ExecutionAbortedError = class extends Error {
25
25
  }
26
26
  };
27
27
 
28
- // src/error/RuntimeError.ts
29
- var RuntimeError = class extends Error {
30
- constructor(message) {
31
- super(message);
32
- this.name = "RuntimeError";
33
- this.retryable = true;
34
- this.catchable = true;
35
- }
36
- get isRetryable() {
37
- return this.retryable;
38
- }
39
- get isCatchable() {
40
- return this.catchable;
28
+ // src/error/ExecutionTimeoutError.ts
29
+ var ExecutionTimeoutError = class extends Error {
30
+ constructor() {
31
+ super("Execution timed out");
32
+ this.name = "ExecutionTimeoutError";
41
33
  }
42
34
  };
43
35
 
44
- // src/error/predefined/StatesTimeoutError.ts
45
- var StatesTimeoutError = class extends RuntimeError {
46
- constructor() {
47
- super("States.Timeout");
48
- this.name = "States.Timeout";
36
+ // src/error/ErrorWithCause.ts
37
+ var _errorCause;
38
+ var ErrorWithCause = class extends Error {
39
+ constructor(message, options) {
40
+ super(message);
41
+ __privateAdd(this, _errorCause, void 0);
42
+ __privateSet(this, _errorCause, options?.cause);
43
+ }
44
+ get cause() {
45
+ return __privateGet(this, _errorCause);
49
46
  }
50
47
  };
48
+ _errorCause = new WeakMap();
51
49
 
52
50
  // src/error/ExecutionError.ts
53
- var _wrappedError;
54
- var ExecutionError = class extends Error {
51
+ var ExecutionError = class extends ErrorWithCause {
55
52
  constructor(caughtError) {
56
- super(`Execution has failed with the following error: ${caughtError.message}`);
57
- __privateAdd(this, _wrappedError, void 0);
53
+ super(`Execution has failed with the following error: ${caughtError.message}`, { cause: caughtError });
58
54
  this.name = "ExecutionError";
59
- __privateSet(this, _wrappedError, caughtError);
60
- }
61
- get getWrappedError() {
62
- return __privateGet(this, _wrappedError);
63
55
  }
64
56
  };
65
- _wrappedError = new WeakMap();
66
57
 
67
58
  // src/util/random.ts
68
59
  function cyrb128(str) {
@@ -96,40 +87,65 @@ function sfc32(a, b, c, d) {
96
87
  return (t >>> 0) / 4294967296;
97
88
  };
98
89
  }
99
- function getRandomNumber(min, max, rngGenerator = Math.random) {
100
- return Math.floor(rngGenerator() * (max - min + 1)) + min;
90
+ function getRandomNumber(min, max, rng = Math.random) {
91
+ return Math.floor(rng() * (max - min + 1)) + min;
101
92
  }
102
93
 
103
94
  // src/util/index.ts
95
+ var isBrowserEnvironment = typeof window !== "undefined" && typeof window.document !== "undefined";
104
96
  function isPlainObj(value) {
105
97
  return !!value && Object.getPrototypeOf(value) === Object.prototype;
106
98
  }
107
99
  function sleep(ms, abortSignal) {
108
100
  return new Promise((resolve) => {
109
- const timeout = setTimeout(resolve, ms);
110
- abortSignal?.addEventListener("abort", () => {
101
+ if (abortSignal?.aborted) {
102
+ return resolve();
103
+ }
104
+ const onAbort = () => {
111
105
  clearTimeout(timeout);
112
- });
106
+ resolve();
107
+ };
108
+ const timeout = setTimeout(() => {
109
+ abortSignal?.removeEventListener("abort", onAbort);
110
+ resolve();
111
+ }, ms);
112
+ abortSignal?.addEventListener("abort", onAbort, { once: true });
113
113
  });
114
114
  }
115
115
  function byteToHex(byte) {
116
116
  return byte.toString(16).padStart(2, "0");
117
117
  }
118
+ function isRFC3339Timestamp(date) {
119
+ const regex = /^\d{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])(\.\d+)?(Z|(\+|-)([01][0-9]|2[0-3]):([0-5][0-9]))$/;
120
+ return regex.test(date);
121
+ }
122
+ function stringifyJSONValue(value) {
123
+ return JSON.stringify(value);
124
+ }
118
125
 
119
- // src/stateMachine/JsonPath.ts
126
+ // src/stateMachine/jsonPath/JsonPath.ts
120
127
  import { JSONPath as jp } from "jsonpath-plus";
121
- function jsonPathQuery(pathExpression, json, context) {
122
- if (pathExpression.startsWith("$$")) {
123
- return jp({ path: pathExpression.slice(1), json: context ?? null, wrap: false });
128
+
129
+ // src/stateMachine/jsonPath/constraints/BaseJsonPathConstraint.ts
130
+ var BaseJSONPathConstraint = class {
131
+ constructor(pathExpression) {
132
+ this.pathExpression = pathExpression;
124
133
  }
125
- return jp({ path: pathExpression, json, wrap: false });
126
- }
134
+ };
127
135
 
128
- // src/error/predefined/StatesResultPathMatchFailureError.ts
129
- var StatesResultPathMatchFailureError = class extends RuntimeError {
130
- constructor() {
131
- super("States.ResultPathMatchFailure");
132
- this.name = "States.ResultPathMatchFailure";
136
+ // src/error/RuntimeError.ts
137
+ var RuntimeError = class extends ErrorWithCause {
138
+ constructor(message, cause) {
139
+ super(message, { cause });
140
+ this.name = "RuntimeError";
141
+ this.retryable = true;
142
+ this.catchable = true;
143
+ }
144
+ get isRetryable() {
145
+ return this.retryable;
146
+ }
147
+ get isCatchable() {
148
+ return this.catchable;
133
149
  }
134
150
  };
135
151
 
@@ -143,6 +159,43 @@ var StatesRuntimeError = class extends RuntimeError {
143
159
  }
144
160
  };
145
161
 
162
+ // src/stateMachine/jsonPath/constraints/DefinedValueConstraint.ts
163
+ var DefinedValueConstraint = class extends BaseJSONPathConstraint {
164
+ test(value) {
165
+ if (typeof value === "undefined") {
166
+ throw new StatesRuntimeError(`Path expression '${this.pathExpression}' does not point to a value`);
167
+ }
168
+ }
169
+ };
170
+
171
+ // src/stateMachine/jsonPath/JsonPath.ts
172
+ function jsonPathQuery(pathExpression, json, context, options) {
173
+ const defaultConstraints = [];
174
+ if (!options?.ignoreDefinedValueConstraint) {
175
+ defaultConstraints.push(DefinedValueConstraint);
176
+ }
177
+ const constraints = [...defaultConstraints, ...options?.constraints ?? []];
178
+ let evaluation;
179
+ if (pathExpression.startsWith("$$")) {
180
+ evaluation = jp({ path: pathExpression.slice(1), json: context ?? null, wrap: false });
181
+ } else {
182
+ evaluation = jp({ path: pathExpression, json, wrap: false });
183
+ }
184
+ for (const Constraint of constraints) {
185
+ const constraintObject = new Constraint(pathExpression);
186
+ constraintObject.test(evaluation);
187
+ }
188
+ return evaluation;
189
+ }
190
+
191
+ // src/error/predefined/StatesResultPathMatchFailureError.ts
192
+ var StatesResultPathMatchFailureError = class extends RuntimeError {
193
+ constructor() {
194
+ super("States.ResultPathMatchFailure");
195
+ this.name = "States.ResultPathMatchFailure";
196
+ }
197
+ };
198
+
146
199
  // src/stateMachine/intrinsicFunctions/ArgumentHandling.ts
147
200
  function validateArgumentType(allowedTypes, argPosition, funcArg, funcName) {
148
201
  let matchesAllowedType = false;
@@ -859,8 +912,9 @@ function processOutputPath(path, result, context) {
859
912
 
860
913
  // src/stateMachine/stateActions/BaseStateAction.ts
861
914
  var BaseStateAction = class {
862
- constructor(stateDefinition) {
915
+ constructor(stateDefinition, stateName) {
863
916
  this.stateDefinition = stateDefinition;
917
+ this.stateName = stateName;
864
918
  }
865
919
  buildExecutionResult(stateResult) {
866
920
  const executionResult = { stateResult, nextState: "", isEndState: false };
@@ -882,212 +936,300 @@ var StatesNoChoiceMatchedError = class extends RuntimeError {
882
936
  }
883
937
  };
884
938
 
939
+ // src/stateMachine/jsonPath/constraints/StringConstraint.ts
940
+ var StringConstraint = class extends BaseJSONPathConstraint {
941
+ test(value) {
942
+ if (typeof value !== "string") {
943
+ throw new StatesRuntimeError(
944
+ `Path expression '${this.pathExpression}' evaluated to ${stringifyJSONValue(value)}, but expected a string`
945
+ );
946
+ }
947
+ }
948
+ };
949
+
950
+ // src/stateMachine/jsonPath/constraints/NumberConstraint.ts
951
+ var NumberConstraint = class extends BaseJSONPathConstraint {
952
+ test(value) {
953
+ if (typeof value !== "number") {
954
+ throw new StatesRuntimeError(
955
+ `Path expression '${this.pathExpression}' evaluated to ${stringifyJSONValue(value)}, but expected a number`
956
+ );
957
+ }
958
+ }
959
+ };
960
+
961
+ // src/stateMachine/jsonPath/constraints/BooleanConstraint.ts
962
+ var BooleanConstraint = class extends BaseJSONPathConstraint {
963
+ test(value) {
964
+ if (typeof value !== "boolean") {
965
+ throw new StatesRuntimeError(
966
+ `Path expression '${this.pathExpression}' evaluated to ${stringifyJSONValue(value)}, but expected a boolean`
967
+ );
968
+ }
969
+ }
970
+ };
971
+
972
+ // src/stateMachine/jsonPath/constraints/RFC3339TimestampConstraint.ts
973
+ var RFC3339TimestampConstraint = class extends BaseJSONPathConstraint {
974
+ test(value) {
975
+ if (typeof value !== "string" || !isRFC3339Timestamp(value)) {
976
+ throw new StatesRuntimeError(
977
+ `Path expression '${this.pathExpression}' evaluated to ${stringifyJSONValue(
978
+ value
979
+ )}, but expected a timestamp conforming to the RFC3339 profile`
980
+ );
981
+ }
982
+ }
983
+ };
984
+
885
985
  // src/stateMachine/stateActions/ChoiceStateAction.ts
886
986
  import wcmatch from "wildcard-match";
887
987
  var ChoiceStateAction = class extends BaseStateAction {
888
- constructor(stateDefinition) {
889
- super(stateDefinition);
988
+ constructor(stateDefinition, stateName) {
989
+ super(stateDefinition, stateName);
890
990
  }
891
- testChoiceRule(choiceRule, input) {
991
+ testChoiceRule(choiceRule, input, context) {
892
992
  if ("And" in choiceRule) {
893
- return choiceRule.And.every((rule) => this.testChoiceRule(rule, input));
993
+ return choiceRule.And.every((rule) => this.testChoiceRule(rule, input, context));
894
994
  }
895
995
  if ("Or" in choiceRule) {
896
- return choiceRule.Or.some((rule) => this.testChoiceRule(rule, input));
996
+ return choiceRule.Or.some((rule) => this.testChoiceRule(rule, input, context));
897
997
  }
898
998
  if ("Not" in choiceRule) {
899
- return !this.testChoiceRule(choiceRule.Not, input);
999
+ return !this.testChoiceRule(choiceRule.Not, input, context);
900
1000
  }
901
1001
  if ("StringEquals" in choiceRule) {
902
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1002
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
903
1003
  return varValue === choiceRule.StringEquals;
904
1004
  }
905
1005
  if ("StringEqualsPath" in choiceRule) {
906
- const varValue = jsonPathQuery(choiceRule.Variable, input);
907
- const stringValue = jsonPathQuery(choiceRule.StringEqualsPath, input);
1006
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1007
+ const stringValue = jsonPathQuery(choiceRule.StringEqualsPath, input, context, {
1008
+ constraints: [StringConstraint]
1009
+ });
908
1010
  return varValue === stringValue;
909
1011
  }
910
1012
  if ("StringLessThan" in choiceRule) {
911
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1013
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
912
1014
  return varValue < choiceRule.StringLessThan;
913
1015
  }
914
1016
  if ("StringLessThanPath" in choiceRule) {
915
- const varValue = jsonPathQuery(choiceRule.Variable, input);
916
- const stringValue = jsonPathQuery(choiceRule.StringLessThanPath, input);
1017
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1018
+ const stringValue = jsonPathQuery(choiceRule.StringLessThanPath, input, context, {
1019
+ constraints: [StringConstraint]
1020
+ });
917
1021
  return varValue < stringValue;
918
1022
  }
919
1023
  if ("StringGreaterThan" in choiceRule) {
920
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1024
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
921
1025
  return varValue > choiceRule.StringGreaterThan;
922
1026
  }
923
1027
  if ("StringGreaterThanPath" in choiceRule) {
924
- const varValue = jsonPathQuery(choiceRule.Variable, input);
925
- const stringValue = jsonPathQuery(choiceRule.StringGreaterThanPath, input);
1028
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1029
+ const stringValue = jsonPathQuery(choiceRule.StringGreaterThanPath, input, context, {
1030
+ constraints: [StringConstraint]
1031
+ });
926
1032
  return varValue > stringValue;
927
1033
  }
928
1034
  if ("StringLessThanEquals" in choiceRule) {
929
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1035
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
930
1036
  return varValue <= choiceRule.StringLessThanEquals;
931
1037
  }
932
1038
  if ("StringLessThanEqualsPath" in choiceRule) {
933
- const varValue = jsonPathQuery(choiceRule.Variable, input);
934
- const stringValue = jsonPathQuery(choiceRule.StringLessThanEqualsPath, input);
1039
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1040
+ const stringValue = jsonPathQuery(choiceRule.StringLessThanEqualsPath, input, context, {
1041
+ constraints: [StringConstraint]
1042
+ });
935
1043
  return varValue <= stringValue;
936
1044
  }
937
1045
  if ("StringGreaterThanEquals" in choiceRule) {
938
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1046
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
939
1047
  return varValue >= choiceRule.StringGreaterThanEquals;
940
1048
  }
941
1049
  if ("StringGreaterThanEqualsPath" in choiceRule) {
942
- const varValue = jsonPathQuery(choiceRule.Variable, input);
943
- const stringValue = jsonPathQuery(choiceRule.StringGreaterThanEqualsPath, input);
1050
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1051
+ const stringValue = jsonPathQuery(choiceRule.StringGreaterThanEqualsPath, input, context, {
1052
+ constraints: [StringConstraint]
1053
+ });
944
1054
  return varValue >= stringValue;
945
1055
  }
946
1056
  if ("StringMatches" in choiceRule) {
947
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1057
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
948
1058
  const isMatch = wcmatch(choiceRule.StringMatches, { separator: false });
949
1059
  return isMatch(varValue);
950
1060
  }
951
1061
  if ("NumericEquals" in choiceRule) {
952
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1062
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
953
1063
  return varValue === choiceRule.NumericEquals;
954
1064
  }
955
1065
  if ("NumericEqualsPath" in choiceRule) {
956
- const varValue = jsonPathQuery(choiceRule.Variable, input);
957
- const numberValue = jsonPathQuery(choiceRule.NumericEqualsPath, input);
1066
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1067
+ const numberValue = jsonPathQuery(choiceRule.NumericEqualsPath, input, context, {
1068
+ constraints: [NumberConstraint]
1069
+ });
958
1070
  return varValue === numberValue;
959
1071
  }
960
1072
  if ("NumericLessThan" in choiceRule) {
961
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1073
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
962
1074
  return varValue < choiceRule.NumericLessThan;
963
1075
  }
964
1076
  if ("NumericLessThanPath" in choiceRule) {
965
- const varValue = jsonPathQuery(choiceRule.Variable, input);
966
- const numberValue = jsonPathQuery(choiceRule.NumericLessThanPath, input);
1077
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1078
+ const numberValue = jsonPathQuery(choiceRule.NumericLessThanPath, input, context, {
1079
+ constraints: [NumberConstraint]
1080
+ });
967
1081
  return varValue < numberValue;
968
1082
  }
969
1083
  if ("NumericGreaterThan" in choiceRule) {
970
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1084
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
971
1085
  return varValue > choiceRule.NumericGreaterThan;
972
1086
  }
973
1087
  if ("NumericGreaterThanPath" in choiceRule) {
974
- const varValue = jsonPathQuery(choiceRule.Variable, input);
975
- const numberValue = jsonPathQuery(choiceRule.NumericGreaterThanPath, input);
1088
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1089
+ const numberValue = jsonPathQuery(choiceRule.NumericGreaterThanPath, input, context, {
1090
+ constraints: [NumberConstraint]
1091
+ });
976
1092
  return varValue > numberValue;
977
1093
  }
978
1094
  if ("NumericLessThanEquals" in choiceRule) {
979
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1095
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
980
1096
  return varValue <= choiceRule.NumericLessThanEquals;
981
1097
  }
982
1098
  if ("NumericLessThanEqualsPath" in choiceRule) {
983
- const varValue = jsonPathQuery(choiceRule.Variable, input);
984
- const numberValue = jsonPathQuery(choiceRule.NumericLessThanEqualsPath, input);
1099
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1100
+ const numberValue = jsonPathQuery(choiceRule.NumericLessThanEqualsPath, input, context, {
1101
+ constraints: [NumberConstraint]
1102
+ });
985
1103
  return varValue <= numberValue;
986
1104
  }
987
1105
  if ("NumericGreaterThanEquals" in choiceRule) {
988
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1106
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
989
1107
  return varValue >= choiceRule.NumericGreaterThanEquals;
990
1108
  }
991
1109
  if ("NumericGreaterThanEqualsPath" in choiceRule) {
992
- const varValue = jsonPathQuery(choiceRule.Variable, input);
993
- const numberValue = jsonPathQuery(choiceRule.NumericGreaterThanEqualsPath, input);
1110
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1111
+ const numberValue = jsonPathQuery(choiceRule.NumericGreaterThanEqualsPath, input, context, {
1112
+ constraints: [NumberConstraint]
1113
+ });
994
1114
  return varValue >= numberValue;
995
1115
  }
996
1116
  if ("BooleanEquals" in choiceRule) {
997
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1117
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
998
1118
  return varValue === choiceRule.BooleanEquals;
999
1119
  }
1000
1120
  if ("BooleanEqualsPath" in choiceRule) {
1001
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1002
- const booleanValue = jsonPathQuery(choiceRule.BooleanEqualsPath, input);
1121
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1122
+ const booleanValue = jsonPathQuery(choiceRule.BooleanEqualsPath, input, context, {
1123
+ constraints: [BooleanConstraint]
1124
+ });
1003
1125
  return varValue === booleanValue;
1004
1126
  }
1005
1127
  if ("TimestampEquals" in choiceRule) {
1006
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1128
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1007
1129
  const timestampValue = new Date(choiceRule.TimestampEquals);
1008
1130
  return varValue.getTime() === timestampValue.getTime();
1009
1131
  }
1010
1132
  if ("TimestampEqualsPath" in choiceRule) {
1011
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1012
- const timestampValue = new Date(jsonPathQuery(choiceRule.TimestampEqualsPath, input));
1133
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1134
+ const timestampValue = new Date(
1135
+ jsonPathQuery(choiceRule.TimestampEqualsPath, input, context, {
1136
+ constraints: [RFC3339TimestampConstraint]
1137
+ })
1138
+ );
1013
1139
  return varValue.getTime() === timestampValue.getTime();
1014
1140
  }
1015
1141
  if ("TimestampLessThan" in choiceRule) {
1016
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1142
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1017
1143
  const timestampValue = new Date(choiceRule.TimestampLessThan);
1018
1144
  return varValue < timestampValue;
1019
1145
  }
1020
1146
  if ("TimestampLessThanPath" in choiceRule) {
1021
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1022
- const timestampValue = new Date(jsonPathQuery(choiceRule.TimestampLessThanPath, input));
1147
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1148
+ const timestampValue = new Date(
1149
+ jsonPathQuery(choiceRule.TimestampLessThanPath, input, context, {
1150
+ constraints: [RFC3339TimestampConstraint]
1151
+ })
1152
+ );
1023
1153
  return varValue < timestampValue;
1024
1154
  }
1025
1155
  if ("TimestampGreaterThan" in choiceRule) {
1026
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1156
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1027
1157
  const timestampValue = new Date(choiceRule.TimestampGreaterThan);
1028
1158
  return varValue > timestampValue;
1029
1159
  }
1030
1160
  if ("TimestampGreaterThanPath" in choiceRule) {
1031
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1032
- const timestampValue = new Date(jsonPathQuery(choiceRule.TimestampGreaterThanPath, input));
1161
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1162
+ const timestampValue = new Date(
1163
+ jsonPathQuery(choiceRule.TimestampGreaterThanPath, input, context, {
1164
+ constraints: [RFC3339TimestampConstraint]
1165
+ })
1166
+ );
1033
1167
  return varValue > timestampValue;
1034
1168
  }
1035
1169
  if ("TimestampLessThanEquals" in choiceRule) {
1036
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1170
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1037
1171
  const timestampValue = new Date(choiceRule.TimestampLessThanEquals);
1038
1172
  return varValue <= timestampValue;
1039
1173
  }
1040
1174
  if ("TimestampLessThanEqualsPath" in choiceRule) {
1041
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1042
- const timestampValue = new Date(jsonPathQuery(choiceRule.TimestampLessThanEqualsPath, input));
1175
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1176
+ const timestampValue = new Date(
1177
+ jsonPathQuery(choiceRule.TimestampLessThanEqualsPath, input, context, {
1178
+ constraints: [RFC3339TimestampConstraint]
1179
+ })
1180
+ );
1043
1181
  return varValue <= timestampValue;
1044
1182
  }
1045
1183
  if ("TimestampGreaterThanEquals" in choiceRule) {
1046
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1184
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1047
1185
  const timestampValue = new Date(choiceRule.TimestampGreaterThanEquals);
1048
1186
  return varValue >= timestampValue;
1049
1187
  }
1050
1188
  if ("TimestampGreaterThanEqualsPath" in choiceRule) {
1051
- const varValue = new Date(jsonPathQuery(choiceRule.Variable, input));
1052
- const timestampValue = new Date(jsonPathQuery(choiceRule.TimestampGreaterThanEqualsPath, input));
1189
+ const varValue = new Date(jsonPathQuery(choiceRule.Variable, input, context));
1190
+ const timestampValue = new Date(
1191
+ jsonPathQuery(choiceRule.TimestampGreaterThanEqualsPath, input, context, {
1192
+ constraints: [RFC3339TimestampConstraint]
1193
+ })
1194
+ );
1053
1195
  return varValue >= timestampValue;
1054
1196
  }
1055
1197
  if ("IsNull" in choiceRule) {
1056
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1198
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1057
1199
  const isNullTrue = choiceRule.IsNull;
1058
1200
  return isNullTrue && varValue === null;
1059
1201
  }
1060
1202
  if ("IsPresent" in choiceRule) {
1061
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1203
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context, { ignoreDefinedValueConstraint: true });
1062
1204
  const IsPresentTrue = choiceRule.IsPresent;
1063
1205
  return IsPresentTrue && varValue !== void 0;
1064
1206
  }
1065
1207
  if ("IsNumeric" in choiceRule) {
1066
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1208
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1067
1209
  const IsNumericTrue = choiceRule.IsNumeric;
1068
1210
  return IsNumericTrue && typeof varValue === "number";
1069
1211
  }
1070
1212
  if ("IsString" in choiceRule) {
1071
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1213
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1072
1214
  const IsStringTrue = choiceRule.IsString;
1073
1215
  return IsStringTrue && typeof varValue === "string";
1074
1216
  }
1075
1217
  if ("IsBoolean" in choiceRule) {
1076
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1218
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1077
1219
  const IsBooleanTrue = choiceRule.IsBoolean;
1078
1220
  return IsBooleanTrue && typeof varValue === "boolean";
1079
1221
  }
1080
1222
  if ("IsTimestamp" in choiceRule) {
1081
- const varValue = jsonPathQuery(choiceRule.Variable, input);
1223
+ const varValue = jsonPathQuery(choiceRule.Variable, input, context);
1082
1224
  const IsTimestampTrue = choiceRule.IsTimestamp;
1083
- return IsTimestampTrue && /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|(\+|-)\d{2}:\d{2})/.test(varValue);
1225
+ return IsTimestampTrue && isRFC3339Timestamp(varValue);
1084
1226
  }
1085
1227
  return false;
1086
1228
  }
1087
1229
  async execute(input, context, options) {
1088
1230
  const state = this.stateDefinition;
1089
1231
  for (const choice of state.Choices) {
1090
- const choiceIsMatch = this.testChoiceRule(choice, input);
1232
+ const choiceIsMatch = this.testChoiceRule(choice, input, context);
1091
1233
  if (choiceIsMatch) {
1092
1234
  return { stateResult: input, nextState: choice.Next, isEndState: false };
1093
1235
  }
@@ -1109,22 +1251,40 @@ var FailStateError = class extends RuntimeError {
1109
1251
 
1110
1252
  // src/stateMachine/stateActions/FailStateAction.ts
1111
1253
  var FailStateAction = class extends BaseStateAction {
1112
- constructor(stateDefinition) {
1113
- super(stateDefinition);
1254
+ constructor(stateDefinition, stateName) {
1255
+ super(stateDefinition, stateName);
1114
1256
  }
1115
1257
  async execute(input, context, options) {
1116
1258
  throw new FailStateError(this.stateDefinition.Error, this.stateDefinition.Cause);
1117
1259
  }
1118
1260
  };
1119
1261
 
1262
+ // src/stateMachine/jsonPath/constraints/ArrayConstraint.ts
1263
+ var ArrayConstraint = class extends BaseJSONPathConstraint {
1264
+ test(value) {
1265
+ if (!Array.isArray(value)) {
1266
+ throw new StatesRuntimeError(
1267
+ `Path expression '${this.pathExpression}' evaluated to ${stringifyJSONValue(value)}, but expected an array`
1268
+ );
1269
+ }
1270
+ }
1271
+ };
1272
+
1120
1273
  // src/stateMachine/stateActions/MapStateAction.ts
1121
1274
  import pLimit from "p-limit";
1122
1275
  var DEFAULT_MAX_CONCURRENCY = 40;
1123
1276
  var MapStateAction = class extends BaseStateAction {
1124
- constructor(stateDefinition) {
1125
- super(stateDefinition);
1277
+ constructor(stateDefinition, stateName) {
1278
+ super(stateDefinition, stateName);
1126
1279
  this.executionAbortFuncs = [];
1127
1280
  }
1281
+ async forwardEventsToRootEventLogger(eventLogger, executionEventLogs, index, parentStateRawInput) {
1282
+ if (!eventLogger)
1283
+ return;
1284
+ for await (const event of executionEventLogs) {
1285
+ eventLogger.forwardNestedMapEvent(event, index, this.stateName, parentStateRawInput);
1286
+ }
1287
+ }
1128
1288
  processItem(stateMachine, item, input, context, index, options) {
1129
1289
  const state = this.stateDefinition;
1130
1290
  let paramValue;
@@ -1137,22 +1297,25 @@ var MapStateAction = class extends BaseStateAction {
1137
1297
  if (state.Parameters) {
1138
1298
  paramValue = processPayloadTemplate(state.Parameters, input, context);
1139
1299
  }
1140
- const execution = stateMachine.run(paramValue ?? item, options?.runOptions);
1300
+ const execution = stateMachine.run(paramValue ?? item, options.runOptions);
1141
1301
  this.executionAbortFuncs.push(execution.abort);
1302
+ this.forwardEventsToRootEventLogger(options.eventLogger, execution.eventLogs, index, options.rawInput);
1142
1303
  return execution.result;
1143
1304
  }
1144
1305
  async execute(input, context, options) {
1145
1306
  const state = this.stateDefinition;
1146
1307
  let items = input;
1147
1308
  if (state.ItemsPath) {
1148
- items = jsonPathQuery(state.ItemsPath, input, context);
1309
+ items = jsonPathQuery(state.ItemsPath, input, context, {
1310
+ constraints: [ArrayConstraint]
1311
+ });
1149
1312
  }
1150
1313
  if (!Array.isArray(items)) {
1151
1314
  throw new StatesRuntimeError("Input of Map state must be an array or ItemsPath property must point to an array");
1152
1315
  }
1153
1316
  const iteratorStateMachine = new StateMachine(state.Iterator, {
1154
- ...options?.stateMachineOptions,
1155
- validationOptions: { _noValidate: true }
1317
+ ...options.stateMachineOptions,
1318
+ validationOptions: { noValidate: true }
1156
1319
  });
1157
1320
  const limit = pLimit(state.MaxConcurrency || DEFAULT_MAX_CONCURRENCY);
1158
1321
  const processedItemsPromise = items.map(
@@ -1164,7 +1327,7 @@ var MapStateAction = class extends BaseStateAction {
1164
1327
  } catch (error) {
1165
1328
  this.executionAbortFuncs.forEach((abort) => abort());
1166
1329
  if (error instanceof ExecutionError) {
1167
- throw error.getWrappedError;
1330
+ throw error.cause;
1168
1331
  }
1169
1332
  throw error;
1170
1333
  } finally {
@@ -1177,17 +1340,25 @@ var MapStateAction = class extends BaseStateAction {
1177
1340
  import pLimit2 from "p-limit";
1178
1341
  var DEFAULT_CONCURRENCY = 40;
1179
1342
  var ParallelStateAction = class extends BaseStateAction {
1180
- constructor(stateDefinition) {
1181
- super(stateDefinition);
1343
+ constructor(stateDefinition, stateName) {
1344
+ super(stateDefinition, stateName);
1182
1345
  this.executionAbortFuncs = [];
1183
1346
  }
1347
+ async forwardEventsToRootEventLogger(eventLogger, executionEventLogs, parentStateRawInput) {
1348
+ if (!eventLogger)
1349
+ return;
1350
+ for await (const event of executionEventLogs) {
1351
+ eventLogger.forwardNestedParallelEvent(event, this.stateName, parentStateRawInput);
1352
+ }
1353
+ }
1184
1354
  processBranch(branch, input, context, options) {
1185
1355
  const stateMachine = new StateMachine(branch, {
1186
- ...options?.stateMachineOptions,
1187
- validationOptions: { _noValidate: true }
1356
+ ...options.stateMachineOptions,
1357
+ validationOptions: { noValidate: true }
1188
1358
  });
1189
- const execution = stateMachine.run(input, options?.runOptions);
1359
+ const execution = stateMachine.run(input, options.runOptions);
1190
1360
  this.executionAbortFuncs.push(execution.abort);
1361
+ this.forwardEventsToRootEventLogger(options.eventLogger, execution.eventLogs, options.rawInput);
1191
1362
  return execution.result;
1192
1363
  }
1193
1364
  async execute(input, context, options) {
@@ -1202,7 +1373,7 @@ var ParallelStateAction = class extends BaseStateAction {
1202
1373
  } catch (error) {
1203
1374
  this.executionAbortFuncs.forEach((abort) => abort());
1204
1375
  if (error instanceof ExecutionError) {
1205
- throw error.getWrappedError;
1376
+ throw error.cause;
1206
1377
  }
1207
1378
  throw error;
1208
1379
  }
@@ -1211,8 +1382,8 @@ var ParallelStateAction = class extends BaseStateAction {
1211
1382
 
1212
1383
  // src/stateMachine/stateActions/PassStateAction.ts
1213
1384
  var PassStateAction = class extends BaseStateAction {
1214
- constructor(stateDefinition) {
1215
- super(stateDefinition);
1385
+ constructor(stateDefinition, stateName) {
1386
+ super(stateDefinition, stateName);
1216
1387
  }
1217
1388
  async execute(input, context, options) {
1218
1389
  if (this.stateDefinition.Result) {
@@ -1224,8 +1395,8 @@ var PassStateAction = class extends BaseStateAction {
1224
1395
 
1225
1396
  // src/stateMachine/stateActions/SucceedStateAction.ts
1226
1397
  var SucceedStateAction = class extends BaseStateAction {
1227
- constructor(stateDefinition) {
1228
- super(stateDefinition);
1398
+ constructor(stateDefinition, stateName) {
1399
+ super(stateDefinition, stateName);
1229
1400
  }
1230
1401
  async execute(input, context, options) {
1231
1402
  return { stateResult: input, nextState: "", isEndState: true };
@@ -1235,13 +1406,28 @@ var SucceedStateAction = class extends BaseStateAction {
1235
1406
  // src/aws/LambdaClient.ts
1236
1407
  import { LambdaClient as AWSLambdaClient, InvokeCommand } from "@aws-sdk/client-lambda";
1237
1408
  import { fromCognitoIdentityPool } from "@aws-sdk/credential-providers";
1409
+
1410
+ // src/error/LambdaInvocationError.ts
1411
+ var LambdaInvocationError = class extends RuntimeError {
1412
+ constructor(name, message, cause) {
1413
+ super(message, cause);
1414
+ this.name = name;
1415
+ }
1416
+ };
1417
+
1418
+ // src/aws/LambdaClient.ts
1238
1419
  var LambdaClient = class {
1239
1420
  constructor(config) {
1240
1421
  this.client = new AWSLambdaClient({});
1241
1422
  if (config) {
1242
1423
  if (!config.region) {
1243
1424
  throw new StatesRuntimeError(
1244
- "'awsConfig' option was specified for state machine, but 'region' property is not set"
1425
+ "'awsConfig' option was specified in state machine constructor, but 'region' property is not set."
1426
+ );
1427
+ }
1428
+ if (!config.credentials) {
1429
+ throw new StatesRuntimeError(
1430
+ "'awsConfig' option was specified in state machine constructor, but 'credentials' property is not set."
1245
1431
  );
1246
1432
  }
1247
1433
  if (config.credentials) {
@@ -1264,6 +1450,12 @@ var LambdaClient = class {
1264
1450
  } else if (config.credentials?.accessKeys) {
1265
1451
  this.client = new AWSLambdaClient({ region: config.region, credentials: config.credentials.accessKeys });
1266
1452
  }
1453
+ } else {
1454
+ if (isBrowserEnvironment) {
1455
+ throw new StatesRuntimeError(
1456
+ "aws-local-stepfunctions is running in a browser environment and your state machine definition contains a state of type 'Task'. In order to invoke the Lambda function, you must provide an AWS region and credentials in the state machine constructor by passing the 'awsConfig' option."
1457
+ );
1458
+ }
1267
1459
  }
1268
1460
  }
1269
1461
  async invokeFunction(funcNameOrArn, payload) {
@@ -1280,7 +1472,11 @@ var LambdaClient = class {
1280
1472
  }
1281
1473
  if (invocationResult.FunctionError) {
1282
1474
  const errorResult = resultValue;
1283
- throw new FailStateError(errorResult.errorType, `Execution of Lambda function '${funcNameOrArn}' failed`);
1475
+ throw new LambdaInvocationError(
1476
+ errorResult.errorType,
1477
+ `${errorResult.errorType}: ${errorResult.errorMessage}`,
1478
+ errorResult
1479
+ );
1284
1480
  }
1285
1481
  return resultValue;
1286
1482
  }
@@ -1288,53 +1484,90 @@ var LambdaClient = class {
1288
1484
 
1289
1485
  // src/stateMachine/stateActions/TaskStateAction.ts
1290
1486
  var TaskStateAction = class extends BaseStateAction {
1291
- constructor(stateDefinition) {
1292
- super(stateDefinition);
1487
+ constructor(stateDefinition, stateName) {
1488
+ super(stateDefinition, stateName);
1293
1489
  }
1294
1490
  async execute(input, context, options) {
1295
1491
  const state = this.stateDefinition;
1296
- if (options?.overrideFn) {
1492
+ if (options.overrideFn) {
1297
1493
  const result2 = await options.overrideFn(input);
1298
1494
  return this.buildExecutionResult(result2);
1299
1495
  }
1300
- const lambdaClient = new LambdaClient(options?.awsConfig);
1496
+ const lambdaClient = new LambdaClient(options.awsConfig);
1301
1497
  const result = await lambdaClient.invokeFunction(state.Resource, input);
1302
1498
  return this.buildExecutionResult(result);
1303
1499
  }
1304
1500
  };
1305
1501
 
1502
+ // src/stateMachine/jsonPath/constraints/IntegerConstraint.ts
1503
+ var IntegerConstraint = class extends BaseJSONPathConstraint {
1504
+ test(value) {
1505
+ if (!Number.isInteger(value)) {
1506
+ throw new StatesRuntimeError(
1507
+ `Path expression '${this.pathExpression}' evaluated to ${stringifyJSONValue(value)}, but expected an integer`
1508
+ );
1509
+ }
1510
+ }
1511
+ static greaterThanOrEqual(n) {
1512
+ return class extends this {
1513
+ test(value) {
1514
+ super.test(value);
1515
+ if (value < n) {
1516
+ throw new StatesRuntimeError(
1517
+ `Path expression '${this.pathExpression}' evaluated to ${stringifyJSONValue(
1518
+ value
1519
+ )}, but expected an integer >= ${n}`
1520
+ );
1521
+ }
1522
+ }
1523
+ };
1524
+ }
1525
+ };
1526
+
1306
1527
  // src/stateMachine/stateActions/WaitStateAction.ts
1307
1528
  var WaitStateAction = class extends BaseStateAction {
1308
- constructor(stateDefinition) {
1309
- super(stateDefinition);
1529
+ constructor(stateDefinition, stateName) {
1530
+ super(stateDefinition, stateName);
1310
1531
  }
1311
1532
  async execute(input, context, options) {
1312
1533
  const state = this.stateDefinition;
1313
- if (options?.waitTimeOverrideOption !== void 0) {
1534
+ if (options.waitTimeOverrideOption !== void 0) {
1314
1535
  await sleep(options.waitTimeOverrideOption, options.abortSignal);
1315
1536
  return this.buildExecutionResult(input);
1316
1537
  }
1317
1538
  if (state.Seconds) {
1318
- await sleep(state.Seconds * 1e3, options?.abortSignal);
1539
+ await sleep(state.Seconds * 1e3, options.abortSignal);
1319
1540
  } else if (state.Timestamp) {
1320
1541
  const dateTimestamp = new Date(state.Timestamp);
1321
1542
  const currentTime = Date.now();
1322
1543
  const timeDiff = dateTimestamp.getTime() - currentTime;
1323
- await sleep(timeDiff, options?.abortSignal);
1544
+ await sleep(timeDiff, options.abortSignal);
1324
1545
  } else if (state.SecondsPath) {
1325
- const seconds = jsonPathQuery(state.SecondsPath, input, context);
1326
- await sleep(seconds * 1e3, options?.abortSignal);
1546
+ const seconds = jsonPathQuery(state.SecondsPath, input, context, {
1547
+ constraints: [IntegerConstraint.greaterThanOrEqual(0)]
1548
+ });
1549
+ await sleep(seconds * 1e3, options.abortSignal);
1327
1550
  } else if (state.TimestampPath) {
1328
- const timestamp = jsonPathQuery(state.TimestampPath, input, context);
1551
+ const timestamp = jsonPathQuery(state.TimestampPath, input, context, {
1552
+ constraints: [RFC3339TimestampConstraint]
1553
+ });
1329
1554
  const dateTimestamp = new Date(timestamp);
1330
1555
  const currentTime = Date.now();
1331
1556
  const timeDiff = dateTimestamp.getTime() - currentTime;
1332
- await sleep(timeDiff, options?.abortSignal);
1557
+ await sleep(timeDiff, options.abortSignal);
1333
1558
  }
1334
1559
  return this.buildExecutionResult(input);
1335
1560
  }
1336
1561
  };
1337
1562
 
1563
+ // src/error/predefined/StatesTimeoutError.ts
1564
+ var StatesTimeoutError = class extends RuntimeError {
1565
+ constructor() {
1566
+ super("States.Timeout");
1567
+ this.name = "States.Timeout";
1568
+ }
1569
+ };
1570
+
1338
1571
  // src/stateMachine/StateExecutor.ts
1339
1572
  import cloneDeep2 from "lodash/cloneDeep.js";
1340
1573
  var DEFAULT_MAX_ATTEMPTS = 3;
@@ -1372,6 +1605,7 @@ var StateExecutor = class {
1372
1605
  } = await this.stateHandlers[this.stateDefinition.Type](
1373
1606
  // @ts-expect-error Indexing `this.stateActions` by non-literal value produces a `never` type for the `this.stateDefinition` parameter of the handler being called
1374
1607
  this.stateDefinition,
1608
+ rawInput,
1375
1609
  processedInput,
1376
1610
  context,
1377
1611
  this.stateName,
@@ -1380,13 +1614,34 @@ var StateExecutor = class {
1380
1614
  const processedResult = this.processResult(currResult, rawInput, context);
1381
1615
  return { stateResult: processedResult, nextState, isEndState };
1382
1616
  } catch (error) {
1383
- const { shouldRetry, waitTimeBeforeRetry } = this.shouldRetry(error);
1384
- if (shouldRetry && waitTimeBeforeRetry) {
1617
+ options.eventLogger.dispatchStateFailedEvent(
1618
+ this.stateName,
1619
+ this.stateDefinition.Type,
1620
+ input,
1621
+ error
1622
+ );
1623
+ const { shouldRetry, waitTimeBeforeRetry, retrierIndex } = this.shouldRetry(error);
1624
+ if (shouldRetry) {
1625
+ const stateDefinition = this.stateDefinition;
1385
1626
  await sleep(waitTimeBeforeRetry, options.abortSignal);
1627
+ options.eventLogger.dispatchStateRetriedEvent(
1628
+ this.stateName,
1629
+ stateDefinition.Type,
1630
+ input,
1631
+ stateDefinition.Retry[retrierIndex],
1632
+ this.retrierAttempts[retrierIndex]
1633
+ );
1386
1634
  return this.execute(input, context, options);
1387
1635
  }
1388
- const { nextState, errorOutput, resultPath } = this.catchError(error);
1636
+ const { nextState, errorOutput, resultPath, catcherIndex } = this.catchError(error);
1389
1637
  if (nextState && errorOutput) {
1638
+ const stateDefinition = this.stateDefinition;
1639
+ options.eventLogger.dispatchStateCaughtEvent(
1640
+ this.stateName,
1641
+ stateDefinition.Type,
1642
+ input,
1643
+ stateDefinition.Catch[catcherIndex]
1644
+ );
1390
1645
  return { stateResult: processResultPath(resultPath, rawInput, errorOutput), nextState, isEndState: false };
1391
1646
  }
1392
1647
  throw error;
@@ -1444,7 +1699,7 @@ var StateExecutor = class {
1444
1699
  if (this.retrierAttempts[i] >= maxAttempts)
1445
1700
  return { shouldRetry: false };
1446
1701
  this.retrierAttempts[i]++;
1447
- return { shouldRetry: true, waitTimeBeforeRetry };
1702
+ return { shouldRetry: true, waitTimeBeforeRetry, retrierIndex: i };
1448
1703
  }
1449
1704
  }
1450
1705
  }
@@ -1472,7 +1727,7 @@ var StateExecutor = class {
1472
1727
  Cause: error.message
1473
1728
  };
1474
1729
  const resultPath = catcher.ResultPath;
1475
- return { nextState, errorOutput, resultPath };
1730
+ return { nextState, errorOutput, resultPath, catcherIndex: i };
1476
1731
  }
1477
1732
  }
1478
1733
  }
@@ -1484,10 +1739,10 @@ var StateExecutor = class {
1484
1739
  * Invokes the Lambda function specified in the `Resource` field
1485
1740
  * and sets the current result of the state machine to the value returned by the Lambda.
1486
1741
  */
1487
- async executeTaskState(stateDefinition, input, context, stateName, options) {
1742
+ async executeTaskState(stateDefinition, rawInput, input, context, stateName, options) {
1488
1743
  const overrideFn = options.runOptions?.overrides?.taskResourceLocalHandlers?.[stateName];
1489
1744
  const awsConfig = options.stateMachineOptions?.awsConfig;
1490
- const taskStateAction = new TaskStateAction(stateDefinition);
1745
+ const taskStateAction = new TaskStateAction(stateDefinition, stateName);
1491
1746
  const executionResult = await taskStateAction.execute(input, context, { overrideFn, awsConfig });
1492
1747
  return executionResult;
1493
1748
  }
@@ -1497,11 +1752,13 @@ var StateExecutor = class {
1497
1752
  * Creates a new state machine for each of the branches specified in the `Branches` field,
1498
1753
  * and then executes each branch state machine by passing them the Parallel state input.
1499
1754
  */
1500
- async executeParallelState(stateDefinition, input, context, stateName, options) {
1501
- const parallelStateAction = new ParallelStateAction(stateDefinition);
1755
+ async executeParallelState(stateDefinition, rawInput, input, context, stateName, options) {
1756
+ const parallelStateAction = new ParallelStateAction(stateDefinition, stateName);
1502
1757
  const executionResult = await parallelStateAction.execute(input, context, {
1503
1758
  stateMachineOptions: options.stateMachineOptions,
1504
- runOptions: options.runOptions
1759
+ runOptions: options.runOptions,
1760
+ eventLogger: options.eventLogger,
1761
+ rawInput
1505
1762
  });
1506
1763
  return executionResult;
1507
1764
  }
@@ -1512,11 +1769,13 @@ var StateExecutor = class {
1512
1769
  * by the `ItemsPath` field, and then processes each item by passing it
1513
1770
  * as the input to the state machine specified in the `Iterator` field.
1514
1771
  */
1515
- async executeMapState(stateDefinition, input, context, stateName, options) {
1516
- const mapStateAction = new MapStateAction(stateDefinition);
1772
+ async executeMapState(stateDefinition, rawInput, input, context, stateName, options) {
1773
+ const mapStateAction = new MapStateAction(stateDefinition, stateName);
1517
1774
  const executionResult = await mapStateAction.execute(input, context, {
1518
1775
  stateMachineOptions: options.stateMachineOptions,
1519
- runOptions: options.runOptions
1776
+ runOptions: options.runOptions,
1777
+ eventLogger: options.eventLogger,
1778
+ rawInput
1520
1779
  });
1521
1780
  return executionResult;
1522
1781
  }
@@ -1526,8 +1785,8 @@ var StateExecutor = class {
1526
1785
  * If the `Result` field is specified, copies `Result` into the current result.
1527
1786
  * Else, copies the current input into the current result.
1528
1787
  */
1529
- async executePassState(stateDefinition, input, context, stateName, options) {
1530
- const passStateAction = new PassStateAction(stateDefinition);
1788
+ async executePassState(stateDefinition, rawInput, input, context, stateName, options) {
1789
+ const passStateAction = new PassStateAction(stateDefinition, stateName);
1531
1790
  const executionResult = await passStateAction.execute(input, context);
1532
1791
  return executionResult;
1533
1792
  }
@@ -1537,13 +1796,12 @@ var StateExecutor = class {
1537
1796
  * Pauses the state machine execution for a certain amount of time
1538
1797
  * based on one of the `Seconds`, `Timestamp`, `SecondsPath` or `TimestampPath` fields.
1539
1798
  */
1540
- async executeWaitState(stateDefinition, input, context, stateName, options) {
1799
+ async executeWaitState(stateDefinition, rawInput, input, context, stateName, options) {
1541
1800
  const waitTimeOverrideOption = options.runOptions?.overrides?.waitTimeOverrides?.[stateName];
1542
- const abortSignal = options.abortSignal;
1543
- const waitStateAction = new WaitStateAction(stateDefinition);
1801
+ const waitStateAction = new WaitStateAction(stateDefinition, stateName);
1544
1802
  const executionResult = await waitStateAction.execute(input, context, {
1545
1803
  waitTimeOverrideOption,
1546
- abortSignal
1804
+ abortSignal: options.abortSignal
1547
1805
  });
1548
1806
  return executionResult;
1549
1807
  }
@@ -1561,8 +1819,8 @@ var StateExecutor = class {
1561
1819
  * If no rule matches and the `Default` field is not specified, throws a
1562
1820
  * States.NoChoiceMatched error.
1563
1821
  */
1564
- async executeChoiceState(stateDefinition, input, context, stateName, options) {
1565
- const choiceStateAction = new ChoiceStateAction(stateDefinition);
1822
+ async executeChoiceState(stateDefinition, rawInput, input, context, stateName, options) {
1823
+ const choiceStateAction = new ChoiceStateAction(stateDefinition, stateName);
1566
1824
  const executionResult = await choiceStateAction.execute(input, context);
1567
1825
  return executionResult;
1568
1826
  }
@@ -1571,8 +1829,8 @@ var StateExecutor = class {
1571
1829
  *
1572
1830
  * Ends the state machine execution successfully.
1573
1831
  */
1574
- async executeSucceedState(stateDefinition, input, context, stateName, options) {
1575
- const succeedStateAction = new SucceedStateAction(stateDefinition);
1832
+ async executeSucceedState(stateDefinition, rawInput, input, context, stateName, options) {
1833
+ const succeedStateAction = new SucceedStateAction(stateDefinition, stateName);
1576
1834
  const executionResult = await succeedStateAction.execute(input, context);
1577
1835
  return executionResult;
1578
1836
  }
@@ -1581,17 +1839,222 @@ var StateExecutor = class {
1581
1839
  *
1582
1840
  * Ends the state machine execution and marks it as a failure.
1583
1841
  */
1584
- async executeFailState(stateDefinition, input, context, stateName, options) {
1585
- const failStateAction = new FailStateAction(stateDefinition);
1842
+ async executeFailState(stateDefinition, rawInput, input, context, stateName, options) {
1843
+ const failStateAction = new FailStateAction(stateDefinition, stateName);
1586
1844
  const executionResult = await failStateAction.execute(input, context);
1587
1845
  return executionResult;
1588
1846
  }
1589
1847
  };
1590
1848
 
1849
+ // src/stateMachine/EventLogger.ts
1850
+ var EventLogger = class {
1851
+ constructor() {
1852
+ this.eventTarget = new EventTarget();
1853
+ this.eventQueue = [];
1854
+ this.isLoggerClosed = false;
1855
+ }
1856
+ async *getEvents() {
1857
+ while (true) {
1858
+ if (this.eventQueue.length === 0) {
1859
+ await this.waitForNewEvent();
1860
+ }
1861
+ let event = null;
1862
+ while (event = this.eventQueue.shift()) {
1863
+ yield event;
1864
+ }
1865
+ if (this.isLoggerClosed)
1866
+ return;
1867
+ }
1868
+ }
1869
+ /**
1870
+ * Forward nested events created by `Map` states, to the root state machine event logger.
1871
+ * @param event An event dispatched by the nested state machine spawned by a `Map` state.
1872
+ * @param index Index of the current iteration being processed.
1873
+ * @param mapStateName Name of the `Map` state being executed.
1874
+ * @param mapStateRawInput Raw input passed to the `Map` state being executed.
1875
+ */
1876
+ forwardNestedMapEvent(event, index, mapStateName, mapStateRawInput) {
1877
+ switch (event.type) {
1878
+ case "ExecutionStarted":
1879
+ this.dispatchMapIterationStartedEvent(event, index, mapStateName, mapStateRawInput);
1880
+ break;
1881
+ case "ExecutionSucceeded":
1882
+ this.dispatchMapIterationSucceededEvent(event, index, mapStateName, mapStateRawInput);
1883
+ break;
1884
+ case "ExecutionFailed":
1885
+ this.dispatchMapIterationFailedEvent(event, index, mapStateName, mapStateRawInput);
1886
+ break;
1887
+ case "StateEntered":
1888
+ case "StateExited":
1889
+ case "StateFailed":
1890
+ case "StateRetried":
1891
+ case "StateCaught":
1892
+ event.index = index;
1893
+ this.dispatch(event);
1894
+ break;
1895
+ case "ExecutionAborted":
1896
+ case "ExecutionTimeout":
1897
+ return;
1898
+ default:
1899
+ this.dispatch(event);
1900
+ break;
1901
+ }
1902
+ }
1903
+ /**
1904
+ * Forward nested events created by `Parallel` states, to the root state machine event logger.
1905
+ * @param event An event dispatched by the nested state machines spawned by a `Parallel` state.
1906
+ * @param parallelStateName Name of the `Parallel` state being executed.
1907
+ * @param parallelStateRawInput Raw input passed to the `Parallel` state being executed.
1908
+ */
1909
+ forwardNestedParallelEvent(event, parallelStateName, parallelStateRawInput) {
1910
+ switch (event.type) {
1911
+ case "ExecutionStarted":
1912
+ this.dispatchParallelBranchStartedEvent(event, parallelStateName, parallelStateRawInput);
1913
+ break;
1914
+ case "ExecutionSucceeded":
1915
+ this.dispatchParallelBranchSucceededEvent(event, parallelStateName, parallelStateRawInput);
1916
+ break;
1917
+ case "ExecutionFailed":
1918
+ this.dispatchParallelBranchFailedEvent(event, parallelStateName, parallelStateRawInput);
1919
+ break;
1920
+ case "ExecutionAborted":
1921
+ case "ExecutionTimeout":
1922
+ return;
1923
+ default:
1924
+ this.dispatch(event);
1925
+ break;
1926
+ }
1927
+ }
1928
+ dispatchExecutionStartedEvent(input) {
1929
+ this.dispatch({ type: "ExecutionStarted", timestamp: Date.now(), input });
1930
+ }
1931
+ dispatchExecutionSucceededEvent(output) {
1932
+ this.dispatch({ type: "ExecutionSucceeded", timestamp: Date.now(), output });
1933
+ this.close();
1934
+ }
1935
+ dispatchExecutionFailedEvent(error) {
1936
+ this.dispatch({
1937
+ type: "ExecutionFailed",
1938
+ timestamp: Date.now(),
1939
+ Error: error.name,
1940
+ Cause: error.cause ?? error.message
1941
+ });
1942
+ this.close();
1943
+ }
1944
+ dispatchExecutionAbortedEvent() {
1945
+ this.dispatch({ type: "ExecutionAborted", timestamp: Date.now() });
1946
+ this.close();
1947
+ }
1948
+ dispatchExecutionTimeoutEvent() {
1949
+ this.dispatch({ type: "ExecutionTimeout", timestamp: Date.now() });
1950
+ this.close();
1951
+ }
1952
+ dispatchStateEnteredEvent(stateName, stateType, input) {
1953
+ this.dispatch({
1954
+ type: "StateEntered",
1955
+ timestamp: Date.now(),
1956
+ state: { name: stateName, type: stateType, input }
1957
+ });
1958
+ }
1959
+ dispatchStateExitedEvent(stateName, stateType, input, output) {
1960
+ this.dispatch({
1961
+ type: "StateExited",
1962
+ timestamp: Date.now(),
1963
+ state: { name: stateName, type: stateType, input, output }
1964
+ });
1965
+ }
1966
+ dispatchStateFailedEvent(stateName, stateType, input, error) {
1967
+ this.dispatch({
1968
+ type: "StateFailed",
1969
+ timestamp: Date.now(),
1970
+ state: { name: stateName, type: stateType, input },
1971
+ Error: error.name,
1972
+ Cause: error.cause ?? error.message
1973
+ });
1974
+ }
1975
+ dispatchStateRetriedEvent(stateName, stateType, input, retrier, retryAttempt) {
1976
+ this.dispatch({
1977
+ type: "StateRetried",
1978
+ timestamp: Date.now(),
1979
+ state: { name: stateName, type: stateType, input },
1980
+ retry: { retrier, attempt: retryAttempt }
1981
+ });
1982
+ }
1983
+ dispatchStateCaughtEvent(stateName, stateType, input, catcher) {
1984
+ this.dispatch({
1985
+ type: "StateCaught",
1986
+ timestamp: Date.now(),
1987
+ state: { name: stateName, type: stateType, input },
1988
+ catch: { catcher }
1989
+ });
1990
+ }
1991
+ dispatchMapIterationStartedEvent(event, index, mapStateName, mapStateRawInput) {
1992
+ this.dispatch({
1993
+ ...event,
1994
+ type: "MapIterationStarted",
1995
+ index,
1996
+ parentState: { type: "Map", name: mapStateName, input: mapStateRawInput }
1997
+ });
1998
+ }
1999
+ dispatchMapIterationSucceededEvent(event, index, mapStateName, mapStateRawInput) {
2000
+ this.dispatch({
2001
+ ...event,
2002
+ type: "MapIterationSucceeded",
2003
+ index,
2004
+ parentState: { type: "Map", name: mapStateName, input: mapStateRawInput }
2005
+ });
2006
+ }
2007
+ dispatchMapIterationFailedEvent(event, index, mapStateName, mapStateRawInput) {
2008
+ this.dispatch({
2009
+ ...event,
2010
+ type: "MapIterationFailed",
2011
+ index,
2012
+ parentState: { type: "Map", name: mapStateName, input: mapStateRawInput }
2013
+ });
2014
+ }
2015
+ dispatchParallelBranchStartedEvent(event, parallelStateName, parallelStateRawInput) {
2016
+ this.dispatch({
2017
+ ...event,
2018
+ type: "ParallelBranchStarted",
2019
+ parentState: { type: "Parallel", name: parallelStateName, input: parallelStateRawInput }
2020
+ });
2021
+ }
2022
+ dispatchParallelBranchSucceededEvent(event, parallelStateName, parallelStateRawInput) {
2023
+ this.dispatch({
2024
+ ...event,
2025
+ type: "ParallelBranchSucceeded",
2026
+ parentState: { type: "Parallel", name: parallelStateName, input: parallelStateRawInput }
2027
+ });
2028
+ }
2029
+ dispatchParallelBranchFailedEvent(event, parallelStateName, parallelStateRawInput) {
2030
+ this.dispatch({
2031
+ ...event,
2032
+ type: "ParallelBranchFailed",
2033
+ parentState: { type: "Parallel", name: parallelStateName, input: parallelStateRawInput }
2034
+ });
2035
+ }
2036
+ close() {
2037
+ this.isLoggerClosed = true;
2038
+ this.eventTarget.dispatchEvent(new Event("newEvent"));
2039
+ }
2040
+ dispatch(event) {
2041
+ if (this.isLoggerClosed)
2042
+ return;
2043
+ this.eventQueue.push(event);
2044
+ this.eventTarget.dispatchEvent(new Event("newEvent"));
2045
+ }
2046
+ waitForNewEvent() {
2047
+ if (this.isLoggerClosed)
2048
+ return;
2049
+ return new Promise((resolve) => {
2050
+ this.eventTarget.addEventListener("newEvent", resolve, { once: true });
2051
+ });
2052
+ }
2053
+ };
2054
+
1591
2055
  // src/stateMachine/StateMachine.ts
1592
2056
  import aslValidator from "asl-validator";
1593
2057
  import cloneDeep3 from "lodash/cloneDeep.js";
1594
- var DEFAULT_MAX_EXECUTION_TIMEOUT = 2147483647e-3;
1595
2058
  var StateMachine = class {
1596
2059
  /**
1597
2060
  * Constructs a new state machine.
@@ -1600,7 +2063,7 @@ var StateMachine = class {
1600
2063
  * These options also apply to state machines defined in the `Iterator` field of `Map` states and in the `Branches` field of `Parallel` states.
1601
2064
  */
1602
2065
  constructor(definition, stateMachineOptions) {
1603
- if (!stateMachineOptions?.validationOptions?._noValidate) {
2066
+ if (!stateMachineOptions?.validationOptions?.noValidate) {
1604
2067
  const { isValid, errorsText } = aslValidator(definition, {
1605
2068
  checkArn: true,
1606
2069
  checkPaths: true,
@@ -1619,6 +2082,9 @@ var StateMachine = class {
1619
2082
  * If the execution fails, the result will throw an `ExecutionError` explaining why the
1620
2083
  * execution failed.
1621
2084
  *
2085
+ * If the execution times out because the number of seconds specified in
2086
+ * the `TimeoutSeconds` top-level field has elapsed, the result will throw an `ExecutionTimeoutError`.
2087
+ *
1622
2088
  * By default, if the execution is aborted, the result will throw an `ExecutionAbortedError`. This behavior can be changed by setting
1623
2089
  * the `noThrowOnAbort` option to `true`, in which case the result will be `null`.
1624
2090
  *
@@ -1627,40 +2093,65 @@ var StateMachine = class {
1627
2093
  */
1628
2094
  run(input, options) {
1629
2095
  const abortController = new AbortController();
1630
- const timeoutSeconds = this.definition.TimeoutSeconds ?? DEFAULT_MAX_EXECUTION_TIMEOUT;
2096
+ const eventLogger = new EventLogger();
2097
+ let rootSignalAbortHandler;
2098
+ if (options?._rootAbortSignal) {
2099
+ rootSignalAbortHandler = () => abortController.abort();
2100
+ if (options._rootAbortSignal.aborted) {
2101
+ rootSignalAbortHandler();
2102
+ } else {
2103
+ options._rootAbortSignal.addEventListener("abort", rootSignalAbortHandler);
2104
+ }
2105
+ }
1631
2106
  let onAbortHandler;
1632
2107
  const settleOnAbort = new Promise((resolve, reject) => {
1633
2108
  if (options?.noThrowOnAbort) {
1634
- onAbortHandler = () => resolve(null);
2109
+ onAbortHandler = () => {
2110
+ eventLogger.dispatchExecutionAbortedEvent();
2111
+ resolve(null);
2112
+ };
1635
2113
  } else {
1636
- onAbortHandler = () => reject(new ExecutionAbortedError());
2114
+ onAbortHandler = () => {
2115
+ eventLogger.dispatchExecutionAbortedEvent();
2116
+ reject(new ExecutionAbortedError());
2117
+ };
1637
2118
  }
1638
2119
  abortController.signal.addEventListener("abort", onAbortHandler);
1639
2120
  });
2121
+ let rejectOnTimeout;
1640
2122
  let timeoutId;
1641
- const rejectOnTimeout = new Promise((_, reject) => {
1642
- timeoutId = setTimeout(() => {
1643
- abortController.signal.removeEventListener("abort", onAbortHandler);
1644
- abortController.abort();
1645
- reject(new StatesTimeoutError());
1646
- }, timeoutSeconds * 1e3);
1647
- });
2123
+ if (this.definition.TimeoutSeconds !== void 0) {
2124
+ rejectOnTimeout = new Promise((_, reject) => {
2125
+ timeoutId = setTimeout(() => {
2126
+ abortController.signal.removeEventListener("abort", onAbortHandler);
2127
+ abortController.abort();
2128
+ eventLogger.dispatchExecutionTimeoutEvent();
2129
+ reject(new ExecutionTimeoutError());
2130
+ }, this.definition.TimeoutSeconds * 1e3);
2131
+ });
2132
+ }
1648
2133
  const executionResult = this.execute(
1649
2134
  input,
1650
2135
  {
1651
2136
  stateMachineOptions: this.stateMachineOptions,
1652
- runOptions: options,
1653
- abortSignal: abortController.signal
2137
+ runOptions: { ...options, _rootAbortSignal: options?._rootAbortSignal ?? abortController.signal },
2138
+ abortSignal: abortController.signal,
2139
+ eventLogger
1654
2140
  },
1655
2141
  () => {
1656
2142
  abortController.signal.removeEventListener("abort", onAbortHandler);
2143
+ options?._rootAbortSignal?.removeEventListener("abort", rootSignalAbortHandler);
1657
2144
  clearTimeout(timeoutId);
1658
2145
  }
1659
2146
  );
1660
- const racingPromises = [executionResult, settleOnAbort, rejectOnTimeout];
2147
+ const racingPromises = [executionResult, settleOnAbort];
2148
+ if (rejectOnTimeout) {
2149
+ racingPromises.push(rejectOnTimeout);
2150
+ }
1661
2151
  const result = Promise.race(racingPromises);
1662
2152
  return {
1663
2153
  abort: () => abortController.abort(),
2154
+ eventLogs: eventLogger.getEvents(),
1664
2155
  result
1665
2156
  };
1666
2157
  }
@@ -1668,32 +2159,37 @@ var StateMachine = class {
1668
2159
  * Helper method that handles the execution of the machine states and the transitions between them.
1669
2160
  */
1670
2161
  async execute(input, options, cleanupFn) {
2162
+ options.eventLogger.dispatchExecutionStartedEvent(input);
2163
+ const context = options.runOptions?.context ?? {};
1671
2164
  let currState = this.definition.States[this.definition.StartAt];
1672
2165
  let currStateName = this.definition.StartAt;
1673
2166
  let currInput = cloneDeep3(input);
1674
2167
  let currResult = null;
1675
2168
  let nextState = "";
1676
2169
  let isEndState = false;
1677
- let context = {};
1678
2170
  try {
1679
2171
  do {
2172
+ options.eventLogger.dispatchStateEnteredEvent(currStateName, currState.Type, currInput);
1680
2173
  const stateExecutor = new StateExecutor(currStateName, currState);
1681
2174
  ({ stateResult: currResult, nextState, isEndState } = await stateExecutor.execute(currInput, context, options));
2175
+ options.eventLogger.dispatchStateExitedEvent(currStateName, currState.Type, currInput, currResult);
1682
2176
  currInput = currResult;
1683
2177
  currState = this.definition.States[nextState];
1684
2178
  currStateName = nextState;
1685
2179
  } while (!isEndState && !options.abortSignal.aborted);
1686
2180
  } catch (error) {
2181
+ options.eventLogger.dispatchExecutionFailedEvent(error);
1687
2182
  throw new ExecutionError(error);
1688
2183
  } finally {
1689
2184
  cleanupFn();
1690
2185
  }
2186
+ options.eventLogger.dispatchExecutionSucceededEvent(currResult);
1691
2187
  return currResult;
1692
2188
  }
1693
2189
  };
1694
2190
  export {
1695
2191
  ExecutionAbortedError,
1696
2192
  ExecutionError,
1697
- StatesTimeoutError as ExecutionTimeoutError,
2193
+ ExecutionTimeoutError,
1698
2194
  StateMachine
1699
2195
  };