@kensio/yulin 1.21.7 → 1.21.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/README.md +22 -2
  2. package/dist/service/lambda/cfn/event-source-mapping/sim-cfn-lambda-event-source-mapping-properties.js +2 -0
  3. package/dist/service/lambda/cfn/event-source-mapping/sim-cfn-lambda-event-source-mapping-property-rules.js +1 -1
  4. package/dist/service/lambda/command/event-source-mapping/create-event-source-mapping-input.d.ts +2 -0
  5. package/dist/service/lambda/command/event-source-mapping/create-event-source-mapping-input.js +4 -0
  6. package/dist/service/lambda/command/event-source-mapping/create-event-source-mapping-refusals.js +0 -5
  7. package/dist/service/lambda/command/event-source-mapping/create-event-source-mapping.handler.d.ts +2 -0
  8. package/dist/service/lambda/command/event-source-mapping/create-event-source-mapping.handler.js +2 -0
  9. package/dist/service/lambda/command/event-source-mapping/sim-lambda-event-source-mapping-commands.d.ts +2 -0
  10. package/dist/service/lambda/destination/sim-lambda-destination-targets.d.ts +2 -1
  11. package/dist/service/lambda/event-source/poll/kinesis/sim-lambda-kinesis-shard-poller.d.ts +0 -4
  12. package/dist/service/lambda/event-source/poll/kinesis/sim-lambda-kinesis-shard-poller.js +10 -15
  13. package/dist/service/lambda/event-source/poll/sim-lambda-dynamodb-stream-event-source-poller.d.ts +1 -6
  14. package/dist/service/lambda/event-source/poll/sim-lambda-dynamodb-stream-event-source-poller.js +9 -27
  15. package/dist/service/lambda/event-source/poll/sim-lambda-dynamodb-stream-polling.d.ts +19 -0
  16. package/dist/service/lambda/event-source/poll/sim-lambda-dynamodb-stream-polling.js +27 -0
  17. package/dist/service/lambda/event-source/poll/sim-lambda-event-source-function.d.ts +1 -1
  18. package/dist/service/lambda/event-source/poll/sim-lambda-event-source-function.js +3 -1
  19. package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-age.d.ts +13 -0
  20. package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-age.js +27 -0
  21. package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-info.d.ts +15 -0
  22. package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-info.js +26 -0
  23. package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-outcome.d.ts +1 -0
  24. package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-outcome.js +7 -1
  25. package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-processing.d.ts +17 -0
  26. package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-processing.js +12 -0
  27. package/dist/service/lambda/event-source/poll/sim-lambda-stream-cursor.d.ts +15 -0
  28. package/dist/service/lambda/event-source/poll/sim-lambda-stream-cursor.js +28 -0
  29. package/dist/service/lambda/event-source/poll/sim-lambda-stream-expiry.d.ts +19 -0
  30. package/dist/service/lambda/event-source/poll/sim-lambda-stream-expiry.js +23 -0
  31. package/dist/service/lambda/event-source/poll/sim-lambda-stream-failure-context.d.ts +3 -0
  32. package/dist/service/lambda/event-source/poll/sim-lambda-stream-failure-context.js +19 -0
  33. package/dist/service/lambda/event-source/poll/sim-lambda-stream-failure-destination.d.ts +15 -0
  34. package/dist/service/lambda/event-source/poll/sim-lambda-stream-failure-destination.js +38 -0
  35. package/dist/service/lambda/event-source/poll/sim-lambda-stream-failure-record.d.ts +41 -0
  36. package/dist/service/lambda/event-source/poll/sim-lambda-stream-failure-record.js +17 -0
  37. package/dist/service/lambda/event-source/poll/sim-lambda-stream-progress-state.d.ts +21 -0
  38. package/dist/service/lambda/event-source/poll/sim-lambda-stream-progress-state.js +39 -0
  39. package/dist/service/lambda/event-source/poll/sim-lambda-stream-progress.d.ts +7 -37
  40. package/dist/service/lambda/event-source/poll/sim-lambda-stream-progress.js +22 -62
  41. package/dist/service/lambda/event-source/poll/sim-lambda-stream-retry.d.ts +4 -39
  42. package/dist/service/lambda/event-source/poll/sim-lambda-stream-retry.js +12 -64
  43. package/dist/service/lambda/event-source/sim-lambda-event-source-mapping.d.ts +10 -3
  44. package/dist/service/lambda/event-source/sim-lambda-event-source-mapping.js +12 -3
  45. package/dist/service/lambda/event-source/sim-lambda-stream-destination-config.d.ts +7 -0
  46. package/dist/service/lambda/event-source/sim-lambda-stream-destination-config.js +38 -0
  47. package/dist/service/lambda/event-source/stream/kinesis/sim-kinesis-event-source-streams.js +1 -0
  48. package/dist/service/lambda/event-source/stream/sim-dynamodb-event-source-stream-reader.js +1 -0
  49. package/dist/service/lambda/event-source/stream/sim-dynamodb-event-source-stream-shard.d.ts +1 -0
  50. package/dist/service/lambda/event-source/stream/sim-dynamodb-event-source-stream-shard.js +7 -0
  51. package/dist/service/lambda/event-source/stream/sim-lambda-event-source-streams.d.ts +1 -0
  52. package/dist/service/lambda/index.d.ts +1 -0
  53. package/dist/service/lambda/sim-lambda-commands.js +1 -0
  54. package/dist/service/ses/command/authorize/sim-ses-authorizer.d.ts +9 -0
  55. package/dist/service/ses/command/authorize/sim-ses-authorizer.js +18 -2
  56. package/dist/service/ses/command/send/sim-ses-send-email.js +2 -1
  57. package/docs/README.md +7 -0
  58. package/docs/ai-skill/README.md +6 -1
  59. package/docs/sdk/README.md +15 -0
  60. package/docs/services/acm/README.md +24 -40
  61. package/docs/services/apigateway/README.md +52 -71
  62. package/docs/services/apigatewayv2/README.md +55 -74
  63. package/docs/services/athena/README.md +17 -26
  64. package/docs/services/backup/README.md +29 -39
  65. package/docs/services/bedrock/README.md +38 -52
  66. package/docs/services/cloudformation/README.md +43 -55
  67. package/docs/services/cloudfront/README.md +69 -95
  68. package/docs/services/cloudwatch/README.md +40 -54
  69. package/docs/services/cognito/README.md +30 -45
  70. package/docs/services/dynamodb/README.md +34 -51
  71. package/docs/services/ecr/README.md +36 -77
  72. package/docs/services/ecs/README.md +26 -46
  73. package/docs/services/elbv2/README.md +19 -29
  74. package/docs/services/eventbridge/README.md +14 -18
  75. package/docs/services/firehose/README.md +24 -32
  76. package/docs/services/glue/README.md +41 -78
  77. package/docs/services/iam/README.md +13 -15
  78. package/docs/services/kinesis/README.md +53 -93
  79. package/docs/services/kms/README.md +22 -32
  80. package/docs/services/lambda/README.md +112 -85
  81. package/docs/services/logs/README.md +41 -50
  82. package/docs/services/organizations/README.md +50 -85
  83. package/docs/services/personalize/README.md +28 -44
  84. package/docs/services/rekognition/README.md +26 -38
  85. package/docs/services/route53/README.md +17 -17
  86. package/docs/services/s3/README.md +47 -51
  87. package/docs/services/scheduler/README.md +41 -52
  88. package/docs/services/secretsmanager/README.md +27 -42
  89. package/docs/services/ses/README.md +24 -34
  90. package/docs/services/sns/README.md +18 -26
  91. package/docs/services/sqs/README.md +14 -14
  92. package/docs/services/ssm/README.md +13 -17
  93. package/docs/services/stepfunctions/README.md +18 -20
  94. package/docs/services/sts/README.md +32 -45
  95. package/docs/services/wafv2/README.md +12 -17
  96. package/docs/testing/README.md +228 -0
  97. package/docs/time/README.md +10 -0
  98. package/llms.txt +1 -0
  99. package/package.json +1 -1
@@ -0,0 +1,3 @@
1
+ import type { SimLambdaStreamFailureRecord, StreamFailureRecordProperties } from "./sim-lambda-stream-failure-record.js";
2
+ /** Build invocation metadata for a stream failure notification. */
3
+ export declare function streamFailureContext(properties: StreamFailureRecordProperties): Pick<SimLambdaStreamFailureRecord, "requestContext" | "responseContext">;
@@ -0,0 +1,19 @@
1
+ import { randomUUID } from "node:crypto";
2
+ /** Build invocation metadata for a stream failure notification. */
3
+ export function streamFailureContext(properties) {
4
+ return {
5
+ requestContext: {
6
+ requestId: randomUUID(),
7
+ functionArn: properties.mapping.functionArn,
8
+ condition: properties.discard.condition,
9
+ approximateInvokeCount: properties.invokeCount,
10
+ },
11
+ ...(properties.invokeCount > 0 && {
12
+ responseContext: {
13
+ statusCode: 200,
14
+ executedVersion: properties.simFunction.version,
15
+ ...(properties.functionError && { functionError: "Unhandled" }),
16
+ },
17
+ }),
18
+ };
19
+ }
@@ -0,0 +1,15 @@
1
+ import type { SimLambdaStreamBatchOutcome } from "./sim-lambda-stream-batch-outcome.js";
2
+ import type { SimLambdaFunction } from "../../function/sim-lambda-function.js";
3
+ import type { SimLambdaEventSourceMapping } from "../sim-lambda-event-source-mapping.js";
4
+ import type { SimLambdaEventSourceStreamProgressBatch } from "../stream/sim-lambda-event-source-streams.js";
5
+ import { type SimLambdaStreamDiscard } from "./sim-lambda-stream-failure-record.js";
6
+ /** Count invocations and send discarded batch metadata through the destination service. */
7
+ export declare class SimLambdaStreamFailureDestination {
8
+ private readonly mapping;
9
+ private invokeCount;
10
+ private functionError;
11
+ constructor(mapping: SimLambdaEventSourceMapping);
12
+ invoked(outcome: SimLambdaStreamBatchOutcome): void;
13
+ reset(): void;
14
+ deliver(discard: SimLambdaStreamDiscard | undefined, batch: SimLambdaEventSourceStreamProgressBatch, simFunction: SimLambdaFunction): Promise<void>;
15
+ }
@@ -0,0 +1,38 @@
1
+ import { SimLambdaDestinationArn } from "../../destination/sim-lambda-destination-arn.js";
2
+ import { simLambdaStreamFailureRecord, } from "./sim-lambda-stream-failure-record.js";
3
+ /** Count invocations and send discarded batch metadata through the destination service. */
4
+ export class SimLambdaStreamFailureDestination {
5
+ mapping;
6
+ invokeCount = 0;
7
+ functionError = false;
8
+ constructor(mapping) {
9
+ this.mapping = mapping;
10
+ }
11
+ invoked(outcome) {
12
+ this.invokeCount += 1;
13
+ this.functionError = outcome.functionError;
14
+ }
15
+ reset() {
16
+ this.invokeCount = 0;
17
+ }
18
+ async deliver(discard, batch, simFunction) {
19
+ const mapping = this.mapping;
20
+ const arn = mapping.failureDestinationArn;
21
+ if (discard === undefined || arn === undefined || arn === "")
22
+ return;
23
+ const record = simLambdaStreamFailureRecord({
24
+ mapping,
25
+ simFunction,
26
+ discard,
27
+ invokeCount: this.invokeCount,
28
+ shardId: batch.shardId,
29
+ functionError: this.functionError,
30
+ });
31
+ await mapping.destinations.deliver({
32
+ destinationArn: SimLambdaDestinationArn.of(arn),
33
+ sourceFunctionArn: mapping.functionArn,
34
+ sourceFunctionRoleArn: simFunction.roleArn,
35
+ record,
36
+ });
37
+ }
38
+ }
@@ -0,0 +1,41 @@
1
+ import { type SimLambdaStreamBatchInfo } from "./sim-lambda-stream-batch-info.js";
2
+ import type { SimLambdaFunction } from "../../function/sim-lambda-function.js";
3
+ import type { SimLambdaEventSourceMapping } from "../sim-lambda-event-source-mapping.js";
4
+ import type { SimLambdaStreamRecordTime } from "./sim-lambda-stream-record-times.js";
5
+ export type SimLambdaStreamFailureCondition = "RetryAttemptsExhausted" | "RecordAgeExceeded";
6
+ export interface SimLambdaStreamDiscard {
7
+ readonly records: readonly SimLambdaStreamRecordTime[];
8
+ readonly condition: SimLambdaStreamFailureCondition;
9
+ readonly at: Date;
10
+ }
11
+ export interface SimLambdaStreamFailureRecord {
12
+ readonly version: string;
13
+ readonly timestamp: string;
14
+ readonly requestContext: {
15
+ readonly requestId: string;
16
+ readonly functionArn: string;
17
+ readonly condition: SimLambdaStreamFailureCondition;
18
+ readonly approximateInvokeCount: number;
19
+ };
20
+ readonly responseContext?: {
21
+ readonly statusCode: number;
22
+ readonly executedVersion: string;
23
+ readonly functionError?: string;
24
+ };
25
+ readonly DDBStreamBatchInfo?: SimLambdaStreamBatchInfo;
26
+ readonly KinesisBatchInfo?: SimLambdaStreamBatchInfo;
27
+ }
28
+ export interface StreamFailureRecordProperties {
29
+ readonly mapping: SimLambdaEventSourceMapping;
30
+ readonly simFunction: SimLambdaFunction;
31
+ readonly shardId: string | undefined;
32
+ readonly discard: SimLambdaStreamDiscard;
33
+ readonly invokeCount: number;
34
+ readonly functionError: boolean;
35
+ }
36
+ /**
37
+ * SQS and SNS receive metadata identifying the discarded records.
38
+ * @see https://docs.aws.amazon.com/lambda/latest/dg/services-dynamodb-errors.html
39
+ * @see https://docs.aws.amazon.com/lambda/latest/dg/kinesis-on-failure-destination.html
40
+ */
41
+ export declare function simLambdaStreamFailureRecord(properties: StreamFailureRecordProperties): SimLambdaStreamFailureRecord;
@@ -0,0 +1,17 @@
1
+ import { streamFailureContext } from "./sim-lambda-stream-failure-context.js";
2
+ import { simLambdaStreamBatchInfo, streamFailureBatchInfo, } from "./sim-lambda-stream-batch-info.js";
3
+ /**
4
+ * SQS and SNS receive metadata identifying the discarded records.
5
+ * @see https://docs.aws.amazon.com/lambda/latest/dg/services-dynamodb-errors.html
6
+ * @see https://docs.aws.amazon.com/lambda/latest/dg/kinesis-on-failure-destination.html
7
+ */
8
+ export function simLambdaStreamFailureRecord(properties) {
9
+ const { mapping, discard, shardId } = properties;
10
+ const info = simLambdaStreamBatchInfo(discard.records, mapping.eventSourceArn, shardId);
11
+ return {
12
+ version: "1.0",
13
+ timestamp: discard.at.toISOString(),
14
+ ...streamFailureContext(properties),
15
+ ...streamFailureBatchInfo(mapping.eventSourceArn, info),
16
+ };
17
+ }
@@ -0,0 +1,21 @@
1
+ import { SimLambdaStreamExpiry } from "./sim-lambda-stream-expiry.js";
2
+ import { SimLambdaStreamFailureDestination } from "./sim-lambda-stream-failure-destination.js";
3
+ import { SimLambdaStreamCursor } from "./sim-lambda-stream-cursor.js";
4
+ import { SimLambdaStreamRetry } from "./sim-lambda-stream-retry.js";
5
+ import type { BackgroundScheduler, BackgroundTask } from "../../../../util/background/background.js";
6
+ import type { SimLambdaEventSourceMapping } from "../sim-lambda-event-source-mapping.js";
7
+ import type { SimLambdaEventSourceStreamProgressBatch } from "../stream/sim-lambda-event-source-streams.js";
8
+ export interface SimLambdaStreamProgressProperties {
9
+ readonly mapping: SimLambdaEventSourceMapping;
10
+ readonly background: BackgroundScheduler;
11
+ readonly poll: BackgroundTask;
12
+ }
13
+ /** Own the per-shard retry state and its expiry and destination collaborators. */
14
+ export declare class SimLambdaStreamProgressState {
15
+ readonly expiry: SimLambdaStreamExpiry;
16
+ readonly failures: SimLambdaStreamFailureDestination;
17
+ readonly cursor: SimLambdaStreamCursor;
18
+ readonly retry: SimLambdaStreamRetry;
19
+ constructor(properties: SimLambdaStreamProgressProperties);
20
+ handled(batch: SimLambdaEventSourceStreamProgressBatch): void;
21
+ }
@@ -0,0 +1,39 @@
1
+ import { SimLambdaStreamExpiry } from "./sim-lambda-stream-expiry.js";
2
+ import { SimLambdaStreamBatchAge } from "./sim-lambda-stream-batch-age.js";
3
+ import { SimLambdaStreamFailureDestination } from "./sim-lambda-stream-failure-destination.js";
4
+ import { SimLambdaStreamCursor } from "./sim-lambda-stream-cursor.js";
5
+ import { SimLambdaStreamRetry } from "./sim-lambda-stream-retry.js";
6
+ import { PollSchedule } from "../../../../util/background/poll-schedule.js";
7
+ import { assertDefined } from "../../../../util/type-guard/defined.js";
8
+ /** Own the per-shard retry state and its expiry and destination collaborators. */
9
+ export class SimLambdaStreamProgressState {
10
+ expiry;
11
+ failures;
12
+ cursor;
13
+ retry;
14
+ constructor(properties) {
15
+ const { mapping, background } = properties;
16
+ this.failures = new SimLambdaStreamFailureDestination(mapping);
17
+ // A stream mapping is refused at creation unless it names a starting
18
+ // position, so one that has got this far without one is the simulator
19
+ // having gone wrong rather than a request having been wrong.
20
+ const { start, streamRetryLimits } = mapping;
21
+ assertDefined(start, "stream mapping start position");
22
+ assertDefined(streamRetryLimits, "stream mapping retry limits");
23
+ this.cursor = new SimLambdaStreamCursor(start, new PollSchedule(properties));
24
+ this.retry = new SimLambdaStreamRetry(streamRetryLimits, background);
25
+ this.expiry = new SimLambdaStreamExpiry({
26
+ age: new SimLambdaStreamBatchAge(streamRetryLimits, background),
27
+ cursor: this.cursor,
28
+ failures: this.failures,
29
+ handled: (batch) => {
30
+ this.handled(batch);
31
+ },
32
+ });
33
+ }
34
+ handled(batch) {
35
+ this.failures.reset();
36
+ this.retry.reset();
37
+ this.cursor.handled(batch);
38
+ }
39
+ }
@@ -1,27 +1,11 @@
1
- import type { BackgroundScheduler, BackgroundTask } from "../../../../util/background/background.js";
2
- import type { SimLambdaEventSourceMapping } from "../sim-lambda-event-source-mapping.js";
1
+ import { type SimLambdaStreamProgressProperties } from "./sim-lambda-stream-progress-state.js";
2
+ import type { SimLambdaStreamRecordTime } from "./sim-lambda-stream-record-times.js";
3
+ import type { SimLambdaFunction } from "../../function/sim-lambda-function.js";
3
4
  import type { SimLambdaEventSourceStreamPosition, SimLambdaEventSourceStreamProgressBatch } from "../stream/sim-lambda-event-source-streams.js";
4
5
  import type { SimLambdaStreamBatchOutcome } from "./sim-lambda-stream-batch-outcome.js";
5
- interface SimLambdaStreamProgressProperties {
6
- readonly mapping: SimLambdaEventSourceMapping;
7
- readonly background: BackgroundScheduler;
8
- readonly poll: BackgroundTask;
9
- }
10
- /**
11
- * How far along its stream one mapping has got, and what it does next.
12
- *
13
- * The two belong together because they are the same decision. A batch the
14
- * function took moves the checkpoint and the mapping reads on; a batch it threw
15
- * on leaves the checkpoint where it is and the mapping tries the same records
16
- * again after a wait; a batch it reported failing partway through moves the
17
- * checkpoint back to the record it named. Nothing behind a failing batch is
18
- * read until it is through, which is what it means for a stream mapping to
19
- * block its shard.
20
- */
6
+ /** Apply a stream batch outcome to its checkpoint and retry schedule. */
21
7
  export declare class SimLambdaStreamProgress {
22
- private readonly checkpoint;
23
- private readonly retry;
24
- private readonly schedule;
8
+ private readonly state;
25
9
  constructor(properties: SimLambdaStreamProgressProperties);
26
10
  /**
27
11
  * Poll as soon as the simulation gets to it.
@@ -39,10 +23,11 @@ export declare class SimLambdaStreamProgress {
39
23
  * than working out a new one each time.
40
24
  */
41
25
  caughtUp(batch: SimLambdaEventSourceStreamProgressBatch): void;
26
+ before(records: readonly SimLambdaStreamRecordTime[], batch: SimLambdaEventSourceStreamProgressBatch, simFunction: SimLambdaFunction): Promise<number>;
42
27
  /**
43
28
  * Take what became of a batch: move past it, or wait and try it again.
44
29
  */
45
- after(outcome: SimLambdaStreamBatchOutcome, batch: SimLambdaEventSourceStreamProgressBatch): void;
30
+ after(outcome: SimLambdaStreamBatchOutcome, batch: SimLambdaEventSourceStreamProgressBatch, simFunction: SimLambdaFunction): Promise<void>;
46
31
  /**
47
32
  * Move past a batch that is finished with, and read on.
48
33
  *
@@ -50,19 +35,4 @@ export declare class SimLambdaStreamProgress {
50
35
  * given up on.
51
36
  */
52
37
  handled(batch: SimLambdaEventSourceStreamProgressBatch): void;
53
- /**
54
- * Wait and hand a failed batch over again, or give up on it.
55
- *
56
- * Giving up discards the records and carries on with the stream, which is
57
- * what AWS does when a stream mapping's error handling runs out. Parking the
58
- * shard instead would be a simulator invention.
59
- *
60
- * A batch runs out either by having had its retries or by every record left
61
- * in it being older than the mapping will carry. Records that aged out of the
62
- * front of a batch are left behind, and the ones behind them go over again,
63
- * so a mapping given a record age keeps working through its shard rather than
64
- * stalling on the oldest record on it.
65
- */
66
- failed(outcome: SimLambdaStreamBatchOutcome, batch: SimLambdaEventSourceStreamProgressBatch): void;
67
38
  }
68
- export {};
@@ -1,47 +1,21 @@
1
- import { assertDefined } from "../../../../util/type-guard/defined.js";
2
- import { PollSchedule } from "../../../../util/background/poll-schedule.js";
3
- import { SimLambdaStreamCheckpoint } from "./sim-lambda-stream-checkpoint.js";
4
- import { SimLambdaStreamRetry } from "./sim-lambda-stream-retry.js";
5
- /**
6
- * How far along its stream one mapping has got, and what it does next.
7
- *
8
- * The two belong together because they are the same decision. A batch the
9
- * function took moves the checkpoint and the mapping reads on; a batch it threw
10
- * on leaves the checkpoint where it is and the mapping tries the same records
11
- * again after a wait; a batch it reported failing partway through moves the
12
- * checkpoint back to the record it named. Nothing behind a failing batch is
13
- * read until it is through, which is what it means for a stream mapping to
14
- * block its shard.
15
- */
1
+ import { SimLambdaStreamProgressState, } from "./sim-lambda-stream-progress-state.js";
2
+ /** Apply a stream batch outcome to its checkpoint and retry schedule. */
16
3
  export class SimLambdaStreamProgress {
17
- checkpoint;
18
- retry;
19
- schedule;
4
+ state;
20
5
  constructor(properties) {
21
- // A stream mapping is refused at creation unless it names a starting
22
- // position, so one that has got this far without one is the simulator
23
- // having gone wrong rather than a request having been wrong.
24
- const { start, streamRetryLimits } = properties.mapping;
25
- assertDefined(start, "stream mapping start position");
26
- assertDefined(streamRetryLimits, "stream mapping retry limits");
27
- this.checkpoint = new SimLambdaStreamCheckpoint(start);
28
- this.retry = new SimLambdaStreamRetry({
29
- limits: streamRetryLimits,
30
- clock: properties.background,
31
- });
32
- this.schedule = new PollSchedule(properties);
6
+ this.state = new SimLambdaStreamProgressState(properties);
33
7
  }
34
8
  /**
35
9
  * Poll as soon as the simulation gets to it.
36
10
  */
37
11
  pollNow() {
38
- this.schedule.now();
12
+ this.state.cursor.pollNow();
39
13
  }
40
14
  /**
41
15
  * Where the next read starts.
42
16
  */
43
17
  get position() {
44
- return this.checkpoint.position;
18
+ return this.state.cursor.position;
45
19
  }
46
20
  /**
47
21
  * Take a read that came back with nothing.
@@ -51,17 +25,29 @@ export class SimLambdaStreamProgress {
51
25
  * than working out a new one each time.
52
26
  */
53
27
  caughtUp(batch) {
54
- this.checkpoint.advanceTo(batch.next);
28
+ this.state.cursor.advanceTo(batch.next);
29
+ }
30
+ async before(records, batch, simFunction) {
31
+ return await this.state.expiry.before(records, batch, simFunction);
55
32
  }
56
33
  /**
57
34
  * Take what became of a batch: move past it, or wait and try it again.
58
35
  */
59
- after(outcome, batch) {
36
+ async after(outcome, batch, simFunction) {
37
+ this.state.failures.invoked(outcome);
60
38
  if (outcome.isHandled) {
61
39
  this.handled(batch);
62
40
  return;
63
41
  }
64
- this.failed(outcome, batch);
42
+ const again = this.state.retry.after(outcome, this.position);
43
+ const notification = this.state.failures.deliver(this.state.retry.discarded, batch, simFunction);
44
+ if (again === undefined) {
45
+ this.handled(batch);
46
+ }
47
+ else {
48
+ this.state.cursor.resume(again);
49
+ }
50
+ await notification;
65
51
  }
66
52
  /**
67
53
  * Move past a batch that is finished with, and read on.
@@ -70,32 +56,6 @@ export class SimLambdaStreamProgress {
70
56
  * given up on.
71
57
  */
72
58
  handled(batch) {
73
- this.retry.reset();
74
- this.checkpoint.advanceTo(batch.next);
75
- if (!batch.drained) {
76
- this.schedule.now();
77
- }
78
- }
79
- /**
80
- * Wait and hand a failed batch over again, or give up on it.
81
- *
82
- * Giving up discards the records and carries on with the stream, which is
83
- * what AWS does when a stream mapping's error handling runs out. Parking the
84
- * shard instead would be a simulator invention.
85
- *
86
- * A batch runs out either by having had its retries or by every record left
87
- * in it being older than the mapping will carry. Records that aged out of the
88
- * front of a batch are left behind, and the ones behind them go over again,
89
- * so a mapping given a record age keeps working through its shard rather than
90
- * stalling on the oldest record on it.
91
- */
92
- failed(outcome, batch) {
93
- const again = this.retry.after(outcome, this.checkpoint.position);
94
- if (again === undefined) {
95
- this.handled(batch);
96
- return;
97
- }
98
- this.checkpoint.advanceTo(again.position);
99
- this.schedule.afterSeconds(again.afterSeconds);
59
+ this.state.handled(batch);
100
60
  }
101
61
  }
@@ -1,11 +1,8 @@
1
+ import type { SimLambdaStreamDiscard } from "./sim-lambda-stream-failure-record.js";
1
2
  import type { SimClock } from "../../../../util/clock/sim-clock.js";
2
3
  import type { SimLambdaStreamRetryLimits } from "../sim-lambda-stream-retry-limits.js";
3
4
  import type { SimLambdaEventSourceStreamPosition } from "../stream/sim-lambda-event-source-streams.js";
4
5
  import type { SimLambdaStreamBatchOutcome } from "./sim-lambda-stream-batch-outcome.js";
5
- interface SimLambdaStreamRetryProperties {
6
- readonly limits: SimLambdaStreamRetryLimits;
7
- readonly clock: SimClock;
8
- }
9
6
  /**
10
7
  * One more delivery of a failed batch: where it starts, and how long the
11
8
  * mapping waits first.
@@ -14,26 +11,12 @@ export interface SimLambdaStreamRetryAttempt {
14
11
  readonly position: SimLambdaEventSourceStreamPosition;
15
12
  readonly afterSeconds: number;
16
13
  }
17
- /**
18
- * Whether a failed batch is handed over again, and from which record.
19
- *
20
- * Both of Lambda's failed-batch limits end here because they end the same
21
- * thing. A batch stops being delivered when it has had its retries, and a
22
- * record stops being delivered when it is older than the mapping will carry;
23
- * whichever comes first, what is left of the batch is discarded and the mapping
24
- * reads on. Records age out of the front of a batch, because a batch is in
25
- * stream order, so the answer is one record to start from rather than a list of
26
- * survivors.
27
- *
28
- * Ages are read at the instant the next delivery falls due rather than now,
29
- * because the wait before it is what ages the records out. A record judged now
30
- * would be handed to the function and only then found to be too old.
31
- */
14
+ /** Tracks the retry quota and checkpoint of one failed stream batch. */
32
15
  export declare class SimLambdaStreamRetry {
33
- private readonly limits;
16
+ discarded: SimLambdaStreamDiscard | undefined;
34
17
  private readonly clock;
35
18
  private readonly backoff;
36
- constructor(properties: SimLambdaStreamRetryProperties);
19
+ constructor(limits: SimLambdaStreamRetryLimits, clock: SimClock);
37
20
  /**
38
21
  * The next delivery of a failed batch, or nothing when the batch is finished
39
22
  * with.
@@ -43,22 +26,4 @@ export declare class SimLambdaStreamRetry {
43
26
  * Start counting again, which a batch that is finished with does.
44
27
  */
45
28
  reset(): void;
46
- /**
47
- * Where the next delivery starts, or nothing when every record left in the
48
- * batch has aged out.
49
- */
50
- private retryPosition;
51
- /**
52
- * The first record from `from` on that is still young enough to deliver.
53
- */
54
- private firstLiveIndex;
55
- /**
56
- * When the next delivery falls due, which is what a record's age is judged
57
- * against.
58
- *
59
- * Judging it now would hand a record over and only then notice that it was
60
- * too old to be worth handing over, since the wait is what makes it too old.
61
- */
62
- private deliveryAt;
63
29
  }
64
- export {};
@@ -1,44 +1,29 @@
1
1
  import { SimLambdaStreamRetryBackoff } from "./sim-lambda-stream-retry-backoff.js";
2
- const millisecondsPerSecond = 1000;
3
- /**
4
- * Whether a failed batch is handed over again, and from which record.
5
- *
6
- * Both of Lambda's failed-batch limits end here because they end the same
7
- * thing. A batch stops being delivered when it has had its retries, and a
8
- * record stops being delivered when it is older than the mapping will carry;
9
- * whichever comes first, what is left of the batch is discarded and the mapping
10
- * reads on. Records age out of the front of a batch, because a batch is in
11
- * stream order, so the answer is one record to start from rather than a list of
12
- * survivors.
13
- *
14
- * Ages are read at the instant the next delivery falls due rather than now,
15
- * because the wait before it is what ages the records out. A record judged now
16
- * would be handed to the function and only then found to be too old.
17
- */
2
+ /** Tracks the retry quota and checkpoint of one failed stream batch. */
18
3
  export class SimLambdaStreamRetry {
19
- limits;
4
+ discarded;
20
5
  clock;
21
6
  backoff;
22
- constructor(properties) {
23
- this.limits = properties.limits;
24
- this.clock = properties.clock;
25
- this.backoff = new SimLambdaStreamRetryBackoff(properties.limits.attemptLimit);
7
+ constructor(limits, clock) {
8
+ this.clock = clock;
9
+ this.backoff = new SimLambdaStreamRetryBackoff(limits.attemptLimit);
26
10
  }
27
11
  /**
28
12
  * The next delivery of a failed batch, or nothing when the batch is finished
29
13
  * with.
30
14
  */
31
15
  after(outcome, readFrom) {
16
+ this.discarded = undefined;
32
17
  if (this.backoff.isExhausted) {
18
+ this.discarded = {
19
+ records: outcome.records.slice(outcome.retryIndex),
20
+ condition: "RetryAttemptsExhausted",
21
+ at: this.clock.now(),
22
+ };
33
23
  return undefined;
34
24
  }
35
25
  const afterSeconds = this.backoff.nextSeconds();
36
- const deliveryAt = this.deliveryAt(afterSeconds);
37
- const position = this.retryPosition(outcome, readFrom, deliveryAt);
38
- if (position === undefined) {
39
- return undefined;
40
- }
41
- return { position, afterSeconds };
26
+ return { position: outcome.retryPosition(readFrom), afterSeconds };
42
27
  }
43
28
  /**
44
29
  * Start counting again, which a batch that is finished with does.
@@ -46,41 +31,4 @@ export class SimLambdaStreamRetry {
46
31
  reset() {
47
32
  this.backoff.reset();
48
33
  }
49
- /**
50
- * Where the next delivery starts, or nothing when every record left in the
51
- * batch has aged out.
52
- */
53
- retryPosition(outcome, readFrom, deliveryAt) {
54
- const { records, retryIndex } = outcome;
55
- const live = this.firstLiveIndex(records, retryIndex, deliveryAt);
56
- if (live === undefined) {
57
- return undefined;
58
- }
59
- const sequenceNumber = records.at(live)?.sequenceNumber;
60
- // Nothing aged out of the front, so the batch goes back exactly where the
61
- // report left it. A record that aged out but cannot be named leaves the
62
- // batch where it was too, since skipping past a record the mapping cannot
63
- // name would skip the records after it as well.
64
- if (live === retryIndex || sequenceNumber === undefined) {
65
- return outcome.retryPosition(readFrom);
66
- }
67
- return { kind: "sequence", sequenceNumber };
68
- }
69
- /**
70
- * The first record from `from` on that is still young enough to deliver.
71
- */
72
- firstLiveIndex(records, from, deliveryAt) {
73
- const index = records.findIndex((record, position) => position >= from && !this.limits.hasAgedOut(record.at, deliveryAt));
74
- return index === -1 ? undefined : index;
75
- }
76
- /**
77
- * When the next delivery falls due, which is what a record's age is judged
78
- * against.
79
- *
80
- * Judging it now would hand a record over and only then notice that it was
81
- * too old to be worth handing over, since the wait is what makes it too old.
82
- */
83
- deliveryAt(afterSeconds) {
84
- return new Date(this.clock.now().getTime() + afterSeconds * millisecondsPerSecond);
85
- }
86
34
  }
@@ -1,3 +1,5 @@
1
+ import type { SimLambdaStreamDestinationConfiguration } from "./sim-lambda-stream-destination-config.js";
2
+ import type { SimLambdaDestinationTargets } from "../destination/sim-lambda-destination-targets.js";
1
3
  import type { SimAwsAccountRegionScope } from "../../aws/sim-aws-account-region-scope.js";
2
4
  import type { SimLambdaFunctionArn } from "../function/sim-lambda-function-configuration.js";
3
5
  import type { SimLambdaStreamRetryLimits, SimLambdaStreamRetryLimitsConfiguration } from "./sim-lambda-stream-retry-limits.js";
@@ -31,6 +33,8 @@ interface SimLambdaEventSourceMappingProperties {
31
33
  readonly enabled?: boolean | undefined;
32
34
  readonly functionResponseTypes?: readonly SimLambdaFunctionResponseType[] | undefined;
33
35
  readonly streamRetryLimits?: SimLambdaStreamRetryLimits | undefined;
36
+ readonly destinationConfig?: SimLambdaStreamDestinationConfiguration | undefined;
37
+ readonly destinations?: SimLambdaDestinationTargets | undefined;
34
38
  readonly createdAt: Date;
35
39
  }
36
40
  /**
@@ -39,6 +43,7 @@ interface SimLambdaEventSourceMappingProperties {
39
43
  * DeleteEventSourceMapping responses all report it.
40
44
  */
41
45
  export interface SimLambdaEventSourceMappingConfiguration extends Partial<SimLambdaStreamRetryLimitsConfiguration> {
46
+ readonly DestinationConfig?: SimLambdaStreamDestinationConfiguration | undefined;
42
47
  readonly UUID: string;
43
48
  readonly EventSourceMappingArn: SimLambdaEventSourceMappingArn;
44
49
  readonly EventSourceArn: string;
@@ -64,6 +69,7 @@ export interface SimLambdaEventSourceMappingConfiguration extends Partial<SimLam
64
69
  */
65
70
  export declare class SimLambdaEventSourceMapping {
66
71
  #private;
72
+ readonly destinations: SimLambdaDestinationTargets;
67
73
  readonly uuid: string;
68
74
  readonly eventSourceArn: string;
69
75
  readonly functionName: string;
@@ -91,13 +97,14 @@ export declare class SimLambdaEventSourceMapping {
91
97
  * the queue's own problem once the batch comes back.
92
98
  */
93
99
  readonly streamRetryLimits: SimLambdaStreamRetryLimits | undefined;
100
+ private readonly destinationConfig;
94
101
  private readonly accountRegionScope;
95
102
  private readonly enabled;
96
103
  private readonly lastModified;
97
104
  constructor(properties: SimLambdaEventSourceMappingProperties);
98
- /**
99
- * The ARN naming this mapping.
100
- */
105
+ /** The configured failure queue or topic ARN. */
106
+ get failureDestinationArn(): string | undefined;
107
+ /** The ARN naming this mapping. */
101
108
  get arn(): SimLambdaEventSourceMappingArn;
102
109
  /**
103
110
  * The state this mapping is in.
@@ -1,3 +1,4 @@
1
+ import { SimLambdaNoDestinationTargets } from "../destination/sim-lambda-destination-targets.js";
1
2
  import { randomUUID } from "node:crypto";
2
3
  /**
3
4
  * One simulated Lambda event source mapping, from an event source to a
@@ -10,6 +11,7 @@ import { randomUUID } from "node:crypto";
10
11
  * it.
11
12
  */
12
13
  export class SimLambdaEventSourceMapping {
14
+ destinations;
13
15
  uuid = randomUUID();
14
16
  eventSourceArn;
15
17
  functionName;
@@ -37,11 +39,15 @@ export class SimLambdaEventSourceMapping {
37
39
  * the queue's own problem once the batch comes back.
38
40
  */
39
41
  streamRetryLimits;
42
+ destinationConfig;
40
43
  accountRegionScope;
41
44
  enabled;
42
45
  lastModified;
43
46
  #state = "Creating";
44
47
  constructor(properties) {
48
+ this.destinationConfig = properties.destinationConfig;
49
+ this.destinations =
50
+ properties.destinations ?? new SimLambdaNoDestinationTargets();
45
51
  this.accountRegionScope = properties.accountRegionScope;
46
52
  this.eventSourceArn = properties.eventSourceArn;
47
53
  this.functionName = properties.functionName;
@@ -56,9 +62,11 @@ export class SimLambdaEventSourceMapping {
56
62
  this.enabled = properties.enabled ?? true;
57
63
  this.lastModified = properties.createdAt;
58
64
  }
59
- /**
60
- * The ARN naming this mapping.
61
- */
65
+ /** The configured failure queue or topic ARN. */
66
+ get failureDestinationArn() {
67
+ return this.destinationConfig?.OnFailure?.Destination;
68
+ }
69
+ /** The ARN naming this mapping. */
62
70
  get arn() {
63
71
  const { regionName, accountId } = this.accountRegionScope;
64
72
  return `arn:aws:lambda:${regionName}:${accountId}:event-source-mapping:${this.uuid}`;
@@ -96,6 +104,7 @@ export class SimLambdaEventSourceMapping {
96
104
  */
97
105
  configuration() {
98
106
  return {
107
+ DestinationConfig: structuredClone(this.destinationConfig),
99
108
  UUID: this.uuid,
100
109
  EventSourceMappingArn: this.arn,
101
110
  EventSourceArn: this.eventSourceArn,
@@ -0,0 +1,7 @@
1
+ export interface SimLambdaStreamDestinationConfiguration {
2
+ readonly OnFailure?: {
3
+ readonly Destination?: string | undefined;
4
+ } | undefined;
5
+ }
6
+ /** Validate the same destination shape for SDK and CloudFormation requests. */
7
+ export declare function simLambdaStreamDestinationConfig(value: unknown, sourceKind?: string): SimLambdaStreamDestinationConfiguration | undefined;