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