aws-local-stepfunctions 0.6.0 → 1.0.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,27 +63,11 @@ 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;
79
- }
80
- };
81
-
82
- // src/error/predefined/StatesTimeoutError.ts
83
- var StatesTimeoutError = class extends RuntimeError {
66
+ // src/error/ExecutionTimeoutError.ts
67
+ var ExecutionTimeoutError = class extends Error {
84
68
  constructor() {
85
- super("States.Timeout");
86
- this.name = "States.Timeout";
69
+ super("Execution timed out");
70
+ this.name = "ExecutionTimeoutError";
87
71
  }
88
72
  };
89
73
 
@@ -134,20 +118,32 @@ function sfc32(a, b, c, d) {
134
118
  return (t >>> 0) / 4294967296;
135
119
  };
136
120
  }
137
- function getRandomNumber(min, max, rngGenerator = Math.random) {
138
- return Math.floor(rngGenerator() * (max - min + 1)) + min;
121
+ function getRandomNumber(min, max, rng = Math.random) {
122
+ return Math.floor(rng() * (max - min + 1)) + min;
139
123
  }
140
124
 
141
125
  // src/util/index.ts
142
126
  function isPlainObj(value) {
143
127
  return !!value && Object.getPrototypeOf(value) === Object.prototype;
144
128
  }
145
- function sleep(ms, abortSignal) {
129
+ function sleep(ms, abortSignal, rootAbortSignal) {
146
130
  return new Promise((resolve) => {
147
- const timeout = setTimeout(resolve, ms);
148
- abortSignal?.addEventListener("abort", () => {
131
+ if (abortSignal?.aborted || rootAbortSignal?.aborted) {
132
+ return resolve();
133
+ }
134
+ const onAbort = () => {
135
+ abortSignal?.removeEventListener("abort", onAbort);
136
+ rootAbortSignal?.removeEventListener("abort", onAbort);
149
137
  clearTimeout(timeout);
150
- });
138
+ resolve();
139
+ };
140
+ const timeout = setTimeout(() => {
141
+ abortSignal?.removeEventListener("abort", onAbort);
142
+ rootAbortSignal?.removeEventListener("abort", onAbort);
143
+ resolve();
144
+ }, ms);
145
+ abortSignal?.addEventListener("abort", onAbort);
146
+ rootAbortSignal?.addEventListener("abort", onAbort);
151
147
  });
152
148
  }
153
149
  function byteToHex(byte) {
@@ -163,6 +159,22 @@ function jsonPathQuery(pathExpression, json, context) {
163
159
  return (0, import_jsonpath_plus.JSONPath)({ path: pathExpression, json, wrap: false });
164
160
  }
165
161
 
162
+ // src/error/RuntimeError.ts
163
+ var RuntimeError = class extends Error {
164
+ constructor(message) {
165
+ super(message);
166
+ this.name = "RuntimeError";
167
+ this.retryable = true;
168
+ this.catchable = true;
169
+ }
170
+ get isRetryable() {
171
+ return this.retryable;
172
+ }
173
+ get isCatchable() {
174
+ return this.catchable;
175
+ }
176
+ };
177
+
166
178
  // src/error/predefined/StatesResultPathMatchFailureError.ts
167
179
  var StatesResultPathMatchFailureError = class extends RuntimeError {
168
180
  constructor() {
@@ -207,7 +219,7 @@ function validateArgumentType(allowedTypes, argPosition, funcArg, funcName) {
207
219
  if (matchesAllowedType)
208
220
  break;
209
221
  }
210
- const expectedType = allowedTypes.map((type) => `"${type}"`).join(" | ");
222
+ const expectedType = allowedTypes.map((type) => `'${type}'`).join(" | ");
211
223
  if (!matchesAllowedType) {
212
224
  throw new StatesRuntimeError(
213
225
  `Intrinsic function ${funcName} expected argument ${argPosition} to be of type ${expectedType}, but received ${typeof funcArg}`
@@ -235,7 +247,7 @@ function validateArgumentConstraints(argConstraints, argPosition, funcArg, funcN
235
247
  if (matchesAllConstraints)
236
248
  break;
237
249
  }
238
- const expectedConstraints = argConstraints.map((constraint) => `"${constraint}"`).join(" | ");
250
+ const expectedConstraints = argConstraints.map((constraint) => `'${constraint}'`).join(" | ");
239
251
  if (!matchesAllConstraints) {
240
252
  throw new StatesRuntimeError(
241
253
  `Intrinsic function ${funcName} expected argument ${argPosition} to satisfy the following constraints: ${expectedConstraints}`
@@ -857,7 +869,7 @@ function processPayloadTemplate(payloadTemplate, json, context) {
857
869
  let sanitizedKey = key;
858
870
  let resolvedValue = value;
859
871
  if (isPlainObj(value)) {
860
- resolvedValue = processPayloadTemplate(value, json);
872
+ resolvedValue = processPayloadTemplate(value, json, context);
861
873
  }
862
874
  if (key.endsWith(".$") && typeof value === "string") {
863
875
  sanitizedKey = key.replace(".$", "");
@@ -897,8 +909,9 @@ function processOutputPath(path, result, context) {
897
909
 
898
910
  // src/stateMachine/stateActions/BaseStateAction.ts
899
911
  var BaseStateAction = class {
900
- constructor(stateDefinition) {
912
+ constructor(stateDefinition, stateName) {
901
913
  this.stateDefinition = stateDefinition;
914
+ this.stateName = stateName;
902
915
  }
903
916
  buildExecutionResult(stateResult) {
904
917
  const executionResult = { stateResult, nextState: "", isEndState: false };
@@ -923,8 +936,8 @@ var StatesNoChoiceMatchedError = class extends RuntimeError {
923
936
  // src/stateMachine/stateActions/ChoiceStateAction.ts
924
937
  var import_wildcard_match = __toESM(require("wildcard-match"), 1);
925
938
  var ChoiceStateAction = class extends BaseStateAction {
926
- constructor(stateDefinition) {
927
- super(stateDefinition);
939
+ constructor(stateDefinition, stateName) {
940
+ super(stateDefinition, stateName);
928
941
  }
929
942
  testChoiceRule(choiceRule, input) {
930
943
  if ("And" in choiceRule) {
@@ -1147,8 +1160,8 @@ var FailStateError = class extends RuntimeError {
1147
1160
 
1148
1161
  // src/stateMachine/stateActions/FailStateAction.ts
1149
1162
  var FailStateAction = class extends BaseStateAction {
1150
- constructor(stateDefinition) {
1151
- super(stateDefinition);
1163
+ constructor(stateDefinition, stateName) {
1164
+ super(stateDefinition, stateName);
1152
1165
  }
1153
1166
  async execute(input, context, options) {
1154
1167
  throw new FailStateError(this.stateDefinition.Error, this.stateDefinition.Cause);
@@ -1159,10 +1172,17 @@ var FailStateAction = class extends BaseStateAction {
1159
1172
  var import_p_limit = __toESM(require("p-limit"), 1);
1160
1173
  var DEFAULT_MAX_CONCURRENCY = 40;
1161
1174
  var MapStateAction = class extends BaseStateAction {
1162
- constructor(stateDefinition) {
1163
- super(stateDefinition);
1175
+ constructor(stateDefinition, stateName) {
1176
+ super(stateDefinition, stateName);
1164
1177
  this.executionAbortFuncs = [];
1165
1178
  }
1179
+ async forwardEventsToRootEventLogger(eventLogger, executionEventLogs, index, parentStateRawInput) {
1180
+ if (!eventLogger)
1181
+ return;
1182
+ for await (const event of executionEventLogs) {
1183
+ eventLogger.forwardNestedMapEvent(event, index, this.stateName, parentStateRawInput);
1184
+ }
1185
+ }
1166
1186
  processItem(stateMachine, item, input, context, index, options) {
1167
1187
  const state = this.stateDefinition;
1168
1188
  let paramValue;
@@ -1177,6 +1197,7 @@ var MapStateAction = class extends BaseStateAction {
1177
1197
  }
1178
1198
  const execution = stateMachine.run(paramValue ?? item, options?.runOptions);
1179
1199
  this.executionAbortFuncs.push(execution.abort);
1200
+ this.forwardEventsToRootEventLogger(options?.eventLogger, execution.eventLogs, index, options?.rawInput);
1180
1201
  return execution.result;
1181
1202
  }
1182
1203
  async execute(input, context, options) {
@@ -1188,7 +1209,10 @@ var MapStateAction = class extends BaseStateAction {
1188
1209
  if (!Array.isArray(items)) {
1189
1210
  throw new StatesRuntimeError("Input of Map state must be an array or ItemsPath property must point to an array");
1190
1211
  }
1191
- const iteratorStateMachine = new StateMachine(state.Iterator, options?.stateMachineOptions);
1212
+ const iteratorStateMachine = new StateMachine(state.Iterator, {
1213
+ ...options?.stateMachineOptions,
1214
+ validationOptions: { _noValidate: true }
1215
+ });
1192
1216
  const limit = (0, import_p_limit.default)(state.MaxConcurrency || DEFAULT_MAX_CONCURRENCY);
1193
1217
  const processedItemsPromise = items.map(
1194
1218
  (item, i) => limit(() => this.processItem(iteratorStateMachine, item, input, context, i, options))
@@ -1212,14 +1236,25 @@ var MapStateAction = class extends BaseStateAction {
1212
1236
  var import_p_limit2 = __toESM(require("p-limit"), 1);
1213
1237
  var DEFAULT_CONCURRENCY = 40;
1214
1238
  var ParallelStateAction = class extends BaseStateAction {
1215
- constructor(stateDefinition) {
1216
- super(stateDefinition);
1239
+ constructor(stateDefinition, stateName) {
1240
+ super(stateDefinition, stateName);
1217
1241
  this.executionAbortFuncs = [];
1218
1242
  }
1243
+ async forwardEventsToRootEventLogger(eventLogger, executionEventLogs, parentStateRawInput) {
1244
+ if (!eventLogger)
1245
+ return;
1246
+ for await (const event of executionEventLogs) {
1247
+ eventLogger.forwardNestedParallelEvent(event, this.stateName, parentStateRawInput);
1248
+ }
1249
+ }
1219
1250
  processBranch(branch, input, context, options) {
1220
- const stateMachine = new StateMachine(branch, options?.stateMachineOptions);
1251
+ const stateMachine = new StateMachine(branch, {
1252
+ ...options?.stateMachineOptions,
1253
+ validationOptions: { _noValidate: true }
1254
+ });
1221
1255
  const execution = stateMachine.run(input, options?.runOptions);
1222
1256
  this.executionAbortFuncs.push(execution.abort);
1257
+ this.forwardEventsToRootEventLogger(options?.eventLogger, execution.eventLogs, options?.rawInput);
1223
1258
  return execution.result;
1224
1259
  }
1225
1260
  async execute(input, context, options) {
@@ -1243,8 +1278,8 @@ var ParallelStateAction = class extends BaseStateAction {
1243
1278
 
1244
1279
  // src/stateMachine/stateActions/PassStateAction.ts
1245
1280
  var PassStateAction = class extends BaseStateAction {
1246
- constructor(stateDefinition) {
1247
- super(stateDefinition);
1281
+ constructor(stateDefinition, stateName) {
1282
+ super(stateDefinition, stateName);
1248
1283
  }
1249
1284
  async execute(input, context, options) {
1250
1285
  if (this.stateDefinition.Result) {
@@ -1256,8 +1291,8 @@ var PassStateAction = class extends BaseStateAction {
1256
1291
 
1257
1292
  // src/stateMachine/stateActions/SucceedStateAction.ts
1258
1293
  var SucceedStateAction = class extends BaseStateAction {
1259
- constructor(stateDefinition) {
1260
- super(stateDefinition);
1294
+ constructor(stateDefinition, stateName) {
1295
+ super(stateDefinition, stateName);
1261
1296
  }
1262
1297
  async execute(input, context, options) {
1263
1298
  return { stateResult: input, nextState: "", isEndState: true };
@@ -1273,12 +1308,12 @@ var LambdaClient = class {
1273
1308
  if (config) {
1274
1309
  if (!config.region) {
1275
1310
  throw new StatesRuntimeError(
1276
- "`awsConfig` option was specified for state machine, but `region` property is not set"
1311
+ "'awsConfig' option was specified for state machine, but 'region' property is not set"
1277
1312
  );
1278
1313
  }
1279
1314
  if (config.credentials) {
1280
1315
  const credentialsTypes = Object.keys(config.credentials);
1281
- const credentialsNames = credentialsTypes.map((name) => `\`${name}\``).join(", ");
1316
+ const credentialsNames = credentialsTypes.map((name) => `'${name}'`).join(", ");
1282
1317
  if (credentialsTypes.length > 1) {
1283
1318
  throw new StatesRuntimeError(
1284
1319
  `More than one type of AWS credentials were specified: ${credentialsNames}. Only one type may be specified`
@@ -1312,7 +1347,7 @@ var LambdaClient = class {
1312
1347
  }
1313
1348
  if (invocationResult.FunctionError) {
1314
1349
  const errorResult = resultValue;
1315
- throw new FailStateError(errorResult.errorType, `Execution of Lambda function "${funcNameOrArn}" failed`);
1350
+ throw new FailStateError(errorResult.errorType, `Execution of Lambda function '${funcNameOrArn}' failed`);
1316
1351
  }
1317
1352
  return resultValue;
1318
1353
  }
@@ -1320,8 +1355,8 @@ var LambdaClient = class {
1320
1355
 
1321
1356
  // src/stateMachine/stateActions/TaskStateAction.ts
1322
1357
  var TaskStateAction = class extends BaseStateAction {
1323
- constructor(stateDefinition) {
1324
- super(stateDefinition);
1358
+ constructor(stateDefinition, stateName) {
1359
+ super(stateDefinition, stateName);
1325
1360
  }
1326
1361
  async execute(input, context, options) {
1327
1362
  const state = this.stateDefinition;
@@ -1337,36 +1372,44 @@ var TaskStateAction = class extends BaseStateAction {
1337
1372
 
1338
1373
  // src/stateMachine/stateActions/WaitStateAction.ts
1339
1374
  var WaitStateAction = class extends BaseStateAction {
1340
- constructor(stateDefinition) {
1341
- super(stateDefinition);
1375
+ constructor(stateDefinition, stateName) {
1376
+ super(stateDefinition, stateName);
1342
1377
  }
1343
1378
  async execute(input, context, options) {
1344
1379
  const state = this.stateDefinition;
1345
1380
  if (options?.waitTimeOverrideOption !== void 0) {
1346
- await sleep(options.waitTimeOverrideOption, options.abortSignal);
1381
+ await sleep(options.waitTimeOverrideOption, options.abortSignal, options.rootAbortSignal);
1347
1382
  return this.buildExecutionResult(input);
1348
1383
  }
1349
1384
  if (state.Seconds) {
1350
- await sleep(state.Seconds * 1e3, options?.abortSignal);
1385
+ await sleep(state.Seconds * 1e3, options?.abortSignal, options?.rootAbortSignal);
1351
1386
  } else if (state.Timestamp) {
1352
1387
  const dateTimestamp = new Date(state.Timestamp);
1353
1388
  const currentTime = Date.now();
1354
1389
  const timeDiff = dateTimestamp.getTime() - currentTime;
1355
- await sleep(timeDiff, options?.abortSignal);
1390
+ await sleep(timeDiff, options?.abortSignal, options?.rootAbortSignal);
1356
1391
  } else if (state.SecondsPath) {
1357
1392
  const seconds = jsonPathQuery(state.SecondsPath, input, context);
1358
- await sleep(seconds * 1e3, options?.abortSignal);
1393
+ await sleep(seconds * 1e3, options?.abortSignal, options?.rootAbortSignal);
1359
1394
  } else if (state.TimestampPath) {
1360
1395
  const timestamp = jsonPathQuery(state.TimestampPath, input, context);
1361
1396
  const dateTimestamp = new Date(timestamp);
1362
1397
  const currentTime = Date.now();
1363
1398
  const timeDiff = dateTimestamp.getTime() - currentTime;
1364
- await sleep(timeDiff, options?.abortSignal);
1399
+ await sleep(timeDiff, options?.abortSignal, options?.rootAbortSignal);
1365
1400
  }
1366
1401
  return this.buildExecutionResult(input);
1367
1402
  }
1368
1403
  };
1369
1404
 
1405
+ // src/error/predefined/StatesTimeoutError.ts
1406
+ var StatesTimeoutError = class extends RuntimeError {
1407
+ constructor() {
1408
+ super("States.Timeout");
1409
+ this.name = "States.Timeout";
1410
+ }
1411
+ };
1412
+
1370
1413
  // src/stateMachine/StateExecutor.ts
1371
1414
  var import_cloneDeep2 = __toESM(require("lodash/cloneDeep.js"), 1);
1372
1415
  var DEFAULT_MAX_ATTEMPTS = 3;
@@ -1404,6 +1447,7 @@ var StateExecutor = class {
1404
1447
  } = await this.stateHandlers[this.stateDefinition.Type](
1405
1448
  // @ts-expect-error Indexing `this.stateActions` by non-literal value produces a `never` type for the `this.stateDefinition` parameter of the handler being called
1406
1449
  this.stateDefinition,
1450
+ rawInput,
1407
1451
  processedInput,
1408
1452
  context,
1409
1453
  this.stateName,
@@ -1414,7 +1458,7 @@ var StateExecutor = class {
1414
1458
  } catch (error) {
1415
1459
  const { shouldRetry, waitTimeBeforeRetry } = this.shouldRetry(error);
1416
1460
  if (shouldRetry && waitTimeBeforeRetry) {
1417
- await sleep(waitTimeBeforeRetry, options.abortSignal);
1461
+ await sleep(waitTimeBeforeRetry, options.abortSignal, options.runOptions?._rootAbortSignal);
1418
1462
  return this.execute(input, context, options);
1419
1463
  }
1420
1464
  const { nextState, errorOutput, resultPath } = this.catchError(error);
@@ -1516,10 +1560,10 @@ var StateExecutor = class {
1516
1560
  * Invokes the Lambda function specified in the `Resource` field
1517
1561
  * and sets the current result of the state machine to the value returned by the Lambda.
1518
1562
  */
1519
- async executeTaskState(stateDefinition, input, context, stateName, options) {
1563
+ async executeTaskState(stateDefinition, rawInput, input, context, stateName, options) {
1520
1564
  const overrideFn = options.runOptions?.overrides?.taskResourceLocalHandlers?.[stateName];
1521
1565
  const awsConfig = options.stateMachineOptions?.awsConfig;
1522
- const taskStateAction = new TaskStateAction(stateDefinition);
1566
+ const taskStateAction = new TaskStateAction(stateDefinition, stateName);
1523
1567
  const executionResult = await taskStateAction.execute(input, context, { overrideFn, awsConfig });
1524
1568
  return executionResult;
1525
1569
  }
@@ -1529,11 +1573,13 @@ var StateExecutor = class {
1529
1573
  * Creates a new state machine for each of the branches specified in the `Branches` field,
1530
1574
  * and then executes each branch state machine by passing them the Parallel state input.
1531
1575
  */
1532
- async executeParallelState(stateDefinition, input, context, stateName, options) {
1533
- const parallelStateAction = new ParallelStateAction(stateDefinition);
1576
+ async executeParallelState(stateDefinition, rawInput, input, context, stateName, options) {
1577
+ const parallelStateAction = new ParallelStateAction(stateDefinition, stateName);
1534
1578
  const executionResult = await parallelStateAction.execute(input, context, {
1535
1579
  stateMachineOptions: options.stateMachineOptions,
1536
- runOptions: options.runOptions
1580
+ runOptions: options.runOptions,
1581
+ eventLogger: options.eventLogger,
1582
+ rawInput
1537
1583
  });
1538
1584
  return executionResult;
1539
1585
  }
@@ -1544,11 +1590,13 @@ var StateExecutor = class {
1544
1590
  * by the `ItemsPath` field, and then processes each item by passing it
1545
1591
  * as the input to the state machine specified in the `Iterator` field.
1546
1592
  */
1547
- async executeMapState(stateDefinition, input, context, stateName, options) {
1548
- const mapStateAction = new MapStateAction(stateDefinition);
1593
+ async executeMapState(stateDefinition, rawInput, input, context, stateName, options) {
1594
+ const mapStateAction = new MapStateAction(stateDefinition, stateName);
1549
1595
  const executionResult = await mapStateAction.execute(input, context, {
1550
1596
  stateMachineOptions: options.stateMachineOptions,
1551
- runOptions: options.runOptions
1597
+ runOptions: options.runOptions,
1598
+ eventLogger: options.eventLogger,
1599
+ rawInput
1552
1600
  });
1553
1601
  return executionResult;
1554
1602
  }
@@ -1558,8 +1606,8 @@ var StateExecutor = class {
1558
1606
  * If the `Result` field is specified, copies `Result` into the current result.
1559
1607
  * Else, copies the current input into the current result.
1560
1608
  */
1561
- async executePassState(stateDefinition, input, context, stateName, options) {
1562
- const passStateAction = new PassStateAction(stateDefinition);
1609
+ async executePassState(stateDefinition, rawInput, input, context, stateName, options) {
1610
+ const passStateAction = new PassStateAction(stateDefinition, stateName);
1563
1611
  const executionResult = await passStateAction.execute(input, context);
1564
1612
  return executionResult;
1565
1613
  }
@@ -1569,13 +1617,13 @@ var StateExecutor = class {
1569
1617
  * Pauses the state machine execution for a certain amount of time
1570
1618
  * based on one of the `Seconds`, `Timestamp`, `SecondsPath` or `TimestampPath` fields.
1571
1619
  */
1572
- async executeWaitState(stateDefinition, input, context, stateName, options) {
1620
+ async executeWaitState(stateDefinition, rawInput, input, context, stateName, options) {
1573
1621
  const waitTimeOverrideOption = options.runOptions?.overrides?.waitTimeOverrides?.[stateName];
1574
- const abortSignal = options.abortSignal;
1575
- const waitStateAction = new WaitStateAction(stateDefinition);
1622
+ const waitStateAction = new WaitStateAction(stateDefinition, stateName);
1576
1623
  const executionResult = await waitStateAction.execute(input, context, {
1577
1624
  waitTimeOverrideOption,
1578
- abortSignal
1625
+ abortSignal: options.abortSignal,
1626
+ rootAbortSignal: options.runOptions?._rootAbortSignal
1579
1627
  });
1580
1628
  return executionResult;
1581
1629
  }
@@ -1593,8 +1641,8 @@ var StateExecutor = class {
1593
1641
  * If no rule matches and the `Default` field is not specified, throws a
1594
1642
  * States.NoChoiceMatched error.
1595
1643
  */
1596
- async executeChoiceState(stateDefinition, input, context, stateName, options) {
1597
- const choiceStateAction = new ChoiceStateAction(stateDefinition);
1644
+ async executeChoiceState(stateDefinition, rawInput, input, context, stateName, options) {
1645
+ const choiceStateAction = new ChoiceStateAction(stateDefinition, stateName);
1598
1646
  const executionResult = await choiceStateAction.execute(input, context);
1599
1647
  return executionResult;
1600
1648
  }
@@ -1603,8 +1651,8 @@ var StateExecutor = class {
1603
1651
  *
1604
1652
  * Ends the state machine execution successfully.
1605
1653
  */
1606
- async executeSucceedState(stateDefinition, input, context, stateName, options) {
1607
- const succeedStateAction = new SucceedStateAction(stateDefinition);
1654
+ async executeSucceedState(stateDefinition, rawInput, input, context, stateName, options) {
1655
+ const succeedStateAction = new SucceedStateAction(stateDefinition, stateName);
1608
1656
  const executionResult = await succeedStateAction.execute(input, context);
1609
1657
  return executionResult;
1610
1658
  }
@@ -1613,13 +1661,186 @@ var StateExecutor = class {
1613
1661
  *
1614
1662
  * Ends the state machine execution and marks it as a failure.
1615
1663
  */
1616
- async executeFailState(stateDefinition, input, context, stateName, options) {
1617
- const failStateAction = new FailStateAction(stateDefinition);
1664
+ async executeFailState(stateDefinition, rawInput, input, context, stateName, options) {
1665
+ const failStateAction = new FailStateAction(stateDefinition, stateName);
1618
1666
  const executionResult = await failStateAction.execute(input, context);
1619
1667
  return executionResult;
1620
1668
  }
1621
1669
  };
1622
1670
 
1671
+ // src/stateMachine/EventLogger.ts
1672
+ var EventLogger = class {
1673
+ constructor() {
1674
+ this.eventTarget = new EventTarget();
1675
+ this.eventQueue = [];
1676
+ this.isLoggerClosed = false;
1677
+ }
1678
+ async *getEvents() {
1679
+ while (true) {
1680
+ if (this.eventQueue.length === 0) {
1681
+ await this.waitForNewEvent();
1682
+ }
1683
+ let event = null;
1684
+ while (event = this.eventQueue.shift()) {
1685
+ yield event;
1686
+ }
1687
+ if (this.isLoggerClosed)
1688
+ return;
1689
+ }
1690
+ }
1691
+ /**
1692
+ * Forward nested events created by `Map` states, to the root state machine event logger.
1693
+ * @param event An event dispatched by the nested state machine spawned by a `Map` state.
1694
+ * @param index Index of the current iteration being processed.
1695
+ * @param mapStateName Name of the `Map` state being executed.
1696
+ * @param mapStateRawInput Raw input passed to the `Map` state being executed.
1697
+ */
1698
+ forwardNestedMapEvent(event, index, mapStateName, mapStateRawInput) {
1699
+ switch (event.type) {
1700
+ case "ExecutionStarted":
1701
+ this.dispatchMapIterationStartedEvent(event, index, mapStateName, mapStateRawInput);
1702
+ break;
1703
+ case "ExecutionSucceeded":
1704
+ this.dispatchMapIterationSucceededEvent(event, index, mapStateName, mapStateRawInput);
1705
+ break;
1706
+ case "ExecutionFailed":
1707
+ this.dispatchMapIterationFailedEvent(event, index, mapStateName, mapStateRawInput);
1708
+ break;
1709
+ case "StateEntered":
1710
+ case "StateExited":
1711
+ event.index = index;
1712
+ this.dispatch(event);
1713
+ break;
1714
+ case "ExecutionAborted":
1715
+ case "ExecutionTimeout":
1716
+ return;
1717
+ default:
1718
+ this.dispatch(event);
1719
+ break;
1720
+ }
1721
+ }
1722
+ /**
1723
+ * Forward nested events created by `Parallel` states, to the root state machine event logger.
1724
+ * @param event An event dispatched by the nested state machines spawned by a `Parallel` state.
1725
+ * @param parallelStateName Name of the `Parallel` state being executed.
1726
+ * @param parallelStateRawInput Raw input passed to the `Parallel` state being executed.
1727
+ */
1728
+ forwardNestedParallelEvent(event, parallelStateName, parallelStateRawInput) {
1729
+ switch (event.type) {
1730
+ case "ExecutionStarted":
1731
+ this.dispatchParallelBranchStartedEvent(event, parallelStateName, parallelStateRawInput);
1732
+ break;
1733
+ case "ExecutionSucceeded":
1734
+ this.dispatchParallelBranchSucceededEvent(event, parallelStateName, parallelStateRawInput);
1735
+ break;
1736
+ case "ExecutionFailed":
1737
+ this.dispatchParallelBranchFailedEvent(event, parallelStateName, parallelStateRawInput);
1738
+ break;
1739
+ case "ExecutionAborted":
1740
+ case "ExecutionTimeout":
1741
+ return;
1742
+ default:
1743
+ this.dispatch(event);
1744
+ break;
1745
+ }
1746
+ }
1747
+ dispatchExecutionStartedEvent(input) {
1748
+ this.dispatch({ type: "ExecutionStarted", timestamp: Date.now(), input });
1749
+ }
1750
+ dispatchExecutionSucceededEvent(output) {
1751
+ this.dispatch({ type: "ExecutionSucceeded", timestamp: Date.now(), output });
1752
+ this.close();
1753
+ }
1754
+ dispatchExecutionFailedEvent(error) {
1755
+ this.dispatch({ type: "ExecutionFailed", timestamp: Date.now(), Error: error.name, Cause: error.message });
1756
+ this.close();
1757
+ }
1758
+ dispatchExecutionAbortedEvent() {
1759
+ this.dispatch({ type: "ExecutionAborted", timestamp: Date.now() });
1760
+ this.close();
1761
+ }
1762
+ dispatchExecutionTimeoutEvent() {
1763
+ this.dispatch({ type: "ExecutionTimeout", timestamp: Date.now() });
1764
+ this.close();
1765
+ }
1766
+ dispatchStateEnteredEvent(stateName, stateType, input) {
1767
+ this.dispatch({
1768
+ type: "StateEntered",
1769
+ timestamp: Date.now(),
1770
+ state: { name: stateName, type: stateType, input }
1771
+ });
1772
+ }
1773
+ dispatchStateExitedEvent(stateName, stateType, input, output) {
1774
+ this.dispatch({
1775
+ type: "StateExited",
1776
+ timestamp: Date.now(),
1777
+ state: { name: stateName, type: stateType, input, output }
1778
+ });
1779
+ }
1780
+ dispatchMapIterationStartedEvent(event, index, mapStateName, mapStateRawInput) {
1781
+ this.dispatch({
1782
+ ...event,
1783
+ type: "MapIterationStarted",
1784
+ index,
1785
+ parentState: { type: "Map", name: mapStateName, input: mapStateRawInput }
1786
+ });
1787
+ }
1788
+ dispatchMapIterationSucceededEvent(event, index, mapStateName, mapStateRawInput) {
1789
+ this.dispatch({
1790
+ ...event,
1791
+ type: "MapIterationSucceeded",
1792
+ index,
1793
+ parentState: { type: "Map", name: mapStateName, input: mapStateRawInput }
1794
+ });
1795
+ }
1796
+ dispatchMapIterationFailedEvent(event, index, mapStateName, mapStateRawInput) {
1797
+ this.dispatch({
1798
+ ...event,
1799
+ type: "MapIterationFailed",
1800
+ index,
1801
+ parentState: { type: "Map", name: mapStateName, input: mapStateRawInput }
1802
+ });
1803
+ }
1804
+ dispatchParallelBranchStartedEvent(event, parallelStateName, parallelStateRawInput) {
1805
+ this.dispatch({
1806
+ ...event,
1807
+ type: "ParallelBranchStarted",
1808
+ parentState: { type: "Parallel", name: parallelStateName, input: parallelStateRawInput }
1809
+ });
1810
+ }
1811
+ dispatchParallelBranchSucceededEvent(event, parallelStateName, parallelStateRawInput) {
1812
+ this.dispatch({
1813
+ ...event,
1814
+ type: "ParallelBranchSucceeded",
1815
+ parentState: { type: "Parallel", name: parallelStateName, input: parallelStateRawInput }
1816
+ });
1817
+ }
1818
+ dispatchParallelBranchFailedEvent(event, parallelStateName, parallelStateRawInput) {
1819
+ this.dispatch({
1820
+ ...event,
1821
+ type: "ParallelBranchFailed",
1822
+ parentState: { type: "Parallel", name: parallelStateName, input: parallelStateRawInput }
1823
+ });
1824
+ }
1825
+ close() {
1826
+ this.isLoggerClosed = true;
1827
+ this.eventTarget.dispatchEvent(new Event("newEvent"));
1828
+ }
1829
+ dispatch(event) {
1830
+ if (this.isLoggerClosed)
1831
+ return;
1832
+ this.eventQueue.push(event);
1833
+ this.eventTarget.dispatchEvent(new Event("newEvent"));
1834
+ }
1835
+ waitForNewEvent() {
1836
+ if (this.isLoggerClosed)
1837
+ return;
1838
+ return new Promise((resolve) => {
1839
+ this.eventTarget.addEventListener("newEvent", resolve, { once: true });
1840
+ });
1841
+ }
1842
+ };
1843
+
1623
1844
  // src/stateMachine/StateMachine.ts
1624
1845
  var import_asl_validator = __toESM(require("asl-validator"), 1);
1625
1846
  var import_cloneDeep3 = __toESM(require("lodash/cloneDeep.js"), 1);
@@ -1631,14 +1852,16 @@ var StateMachine = class {
1631
1852
  * These options also apply to state machines defined in the `Iterator` field of `Map` states and in the `Branches` field of `Parallel` states.
1632
1853
  */
1633
1854
  constructor(definition, stateMachineOptions) {
1634
- const { isValid, errorsText } = (0, import_asl_validator.default)(definition, {
1635
- checkArn: true,
1636
- checkPaths: true,
1637
- ...stateMachineOptions?.validationOptions
1638
- });
1639
- if (!isValid) {
1640
- throw new Error(`State machine definition is invalid, see error(s) below:
1855
+ if (!stateMachineOptions?.validationOptions?._noValidate) {
1856
+ const { isValid, errorsText } = (0, import_asl_validator.default)(definition, {
1857
+ checkArn: true,
1858
+ checkPaths: true,
1859
+ ...stateMachineOptions?.validationOptions
1860
+ });
1861
+ if (!isValid) {
1862
+ throw new Error(`State machine definition is invalid, see error(s) below:
1641
1863
  ${errorsText("\n")}`);
1864
+ }
1642
1865
  }
1643
1866
  this.definition = definition;
1644
1867
  this.stateMachineOptions = stateMachineOptions;
@@ -1648,6 +1871,9 @@ var StateMachine = class {
1648
1871
  * If the execution fails, the result will throw an `ExecutionError` explaining why the
1649
1872
  * execution failed.
1650
1873
  *
1874
+ * If the execution times out because the number of seconds specified in
1875
+ * the `TimeoutSeconds` top-level field has elapsed, the result will throw an `ExecutionTimeoutError`.
1876
+ *
1651
1877
  * By default, if the execution is aborted, the result will throw an `ExecutionAbortedError`. This behavior can be changed by setting
1652
1878
  * the `noThrowOnAbort` option to `true`, in which case the result will be `null`.
1653
1879
  *
@@ -1656,30 +1882,47 @@ var StateMachine = class {
1656
1882
  */
1657
1883
  run(input, options) {
1658
1884
  const abortController = new AbortController();
1885
+ const eventLogger = new EventLogger();
1659
1886
  let onAbortHandler;
1660
1887
  const settleOnAbort = new Promise((resolve, reject) => {
1661
1888
  if (options?.noThrowOnAbort) {
1662
- onAbortHandler = () => resolve(null);
1889
+ onAbortHandler = () => {
1890
+ eventLogger.dispatchExecutionAbortedEvent();
1891
+ resolve(null);
1892
+ };
1663
1893
  } else {
1664
- onAbortHandler = () => reject(new ExecutionAbortedError());
1894
+ onAbortHandler = () => {
1895
+ eventLogger.dispatchExecutionAbortedEvent();
1896
+ reject(new ExecutionAbortedError());
1897
+ };
1665
1898
  }
1666
1899
  abortController.signal.addEventListener("abort", onAbortHandler);
1667
1900
  });
1668
- let rejectOnTimeout = null;
1669
- if (this.definition.TimeoutSeconds) {
1901
+ let rejectOnTimeout;
1902
+ let timeoutId;
1903
+ if (this.definition.TimeoutSeconds !== void 0) {
1670
1904
  rejectOnTimeout = new Promise((_, reject) => {
1671
- setTimeout(() => {
1905
+ timeoutId = setTimeout(() => {
1672
1906
  abortController.signal.removeEventListener("abort", onAbortHandler);
1673
1907
  abortController.abort();
1674
- reject(new StatesTimeoutError());
1908
+ eventLogger.dispatchExecutionTimeoutEvent();
1909
+ reject(new ExecutionTimeoutError());
1675
1910
  }, this.definition.TimeoutSeconds * 1e3);
1676
1911
  });
1677
1912
  }
1678
- const executionResult = this.execute(input, {
1679
- stateMachineOptions: this.stateMachineOptions,
1680
- runOptions: options,
1681
- abortSignal: abortController.signal
1682
- });
1913
+ const executionResult = this.execute(
1914
+ input,
1915
+ {
1916
+ stateMachineOptions: this.stateMachineOptions,
1917
+ runOptions: { ...options, _rootAbortSignal: options?._rootAbortSignal ?? abortController.signal },
1918
+ abortSignal: abortController.signal,
1919
+ eventLogger
1920
+ },
1921
+ () => {
1922
+ abortController.signal.removeEventListener("abort", onAbortHandler);
1923
+ clearTimeout(timeoutId);
1924
+ }
1925
+ );
1683
1926
  const racingPromises = [executionResult, settleOnAbort];
1684
1927
  if (rejectOnTimeout) {
1685
1928
  racingPromises.push(rejectOnTimeout);
@@ -1687,31 +1930,39 @@ var StateMachine = class {
1687
1930
  const result = Promise.race(racingPromises);
1688
1931
  return {
1689
1932
  abort: () => abortController.abort(),
1933
+ eventLogs: eventLogger.getEvents(),
1690
1934
  result
1691
1935
  };
1692
1936
  }
1693
1937
  /**
1694
1938
  * Helper method that handles the execution of the machine states and the transitions between them.
1695
1939
  */
1696
- async execute(input, options) {
1940
+ async execute(input, options, cleanupFn) {
1941
+ options.eventLogger.dispatchExecutionStartedEvent(input);
1942
+ const context = options.runOptions?.context ?? {};
1697
1943
  let currState = this.definition.States[this.definition.StartAt];
1698
1944
  let currStateName = this.definition.StartAt;
1699
1945
  let currInput = (0, import_cloneDeep3.default)(input);
1700
1946
  let currResult = null;
1701
1947
  let nextState = "";
1702
1948
  let isEndState = false;
1703
- let context = {};
1704
1949
  try {
1705
1950
  do {
1951
+ options.eventLogger.dispatchStateEnteredEvent(currStateName, currState.Type, currInput);
1706
1952
  const stateExecutor = new StateExecutor(currStateName, currState);
1707
1953
  ({ stateResult: currResult, nextState, isEndState } = await stateExecutor.execute(currInput, context, options));
1954
+ options.eventLogger.dispatchStateExitedEvent(currStateName, currState.Type, currInput, currResult);
1708
1955
  currInput = currResult;
1709
1956
  currState = this.definition.States[nextState];
1710
1957
  currStateName = nextState;
1711
1958
  } while (!isEndState && !options.abortSignal.aborted);
1712
1959
  } catch (error) {
1960
+ options.eventLogger.dispatchExecutionFailedEvent(error);
1713
1961
  throw new ExecutionError(error);
1962
+ } finally {
1963
+ cleanupFn();
1714
1964
  }
1965
+ options.eventLogger.dispatchExecutionSucceededEvent(currResult);
1715
1966
  return currResult;
1716
1967
  }
1717
1968
  };