@aws/durable-execution-sdk-js 1.1.2 → 2.0.0-alpha.1

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 (63) hide show
  1. package/dist/index.mjs +669 -103
  2. package/dist/index.mjs.map +1 -1
  3. package/dist-cjs/index.js +666 -102
  4. package/dist-cjs/index.js.map +1 -1
  5. package/dist-types/context/durable-context/durable-context.d.ts +5 -0
  6. package/dist-types/context/durable-context/durable-context.d.ts.map +1 -1
  7. package/dist-types/errors/durable-error/durable-error.d.ts +24 -0
  8. package/dist-types/errors/durable-error/durable-error.d.ts.map +1 -1
  9. package/dist-types/errors/non-retryable-errors.d.ts +5 -0
  10. package/dist-types/errors/non-retryable-errors.d.ts.map +1 -0
  11. package/dist-types/handlers/callback-handler/callback.d.ts +2 -2
  12. package/dist-types/handlers/callback-handler/callback.d.ts.map +1 -1
  13. package/dist-types/handlers/concurrent-execution-handler/concurrent-execution-handler.d.ts +4 -2
  14. package/dist-types/handlers/concurrent-execution-handler/concurrent-execution-handler.d.ts.map +1 -1
  15. package/dist-types/handlers/invoke-handler/invoke-handler.d.ts +2 -1
  16. package/dist-types/handlers/invoke-handler/invoke-handler.d.ts.map +1 -1
  17. package/dist-types/handlers/map-handler/map-handler.d.ts.map +1 -1
  18. package/dist-types/handlers/parallel-handler/parallel-handler.d.ts.map +1 -1
  19. package/dist-types/handlers/promise-handler/promise-handler.d.ts +1 -1
  20. package/dist-types/handlers/promise-handler/promise-handler.d.ts.map +1 -1
  21. package/dist-types/handlers/run-in-child-context-handler/run-in-child-context-handler.d.ts +4 -3
  22. package/dist-types/handlers/run-in-child-context-handler/run-in-child-context-handler.d.ts.map +1 -1
  23. package/dist-types/handlers/step-handler/step-handler.d.ts +2 -1
  24. package/dist-types/handlers/step-handler/step-handler.d.ts.map +1 -1
  25. package/dist-types/handlers/wait-for-callback-handler/wait-for-callback-handler.d.ts +2 -1
  26. package/dist-types/handlers/wait-for-callback-handler/wait-for-callback-handler.d.ts.map +1 -1
  27. package/dist-types/handlers/wait-for-condition-handler/wait-for-condition-handler.d.ts +2 -1
  28. package/dist-types/handlers/wait-for-condition-handler/wait-for-condition-handler.d.ts.map +1 -1
  29. package/dist-types/index.d.ts +7 -3
  30. package/dist-types/index.d.ts.map +1 -1
  31. package/dist-types/testing/test-constants.d.ts +6 -0
  32. package/dist-types/testing/test-constants.d.ts.map +1 -1
  33. package/dist-types/types/batch.d.ts +50 -0
  34. package/dist-types/types/batch.d.ts.map +1 -1
  35. package/dist-types/types/child-context.d.ts +5 -0
  36. package/dist-types/types/child-context.d.ts.map +1 -1
  37. package/dist-types/types/durable-context.d.ts +23 -0
  38. package/dist-types/types/durable-context.d.ts.map +1 -1
  39. package/dist-types/utils/checkpoint/checkpoint-manager.d.ts.map +1 -1
  40. package/dist-types/utils/constants/constants.d.ts +6 -0
  41. package/dist-types/utils/constants/constants.d.ts.map +1 -1
  42. package/dist-types/utils/constants/version.d.ts +1 -12
  43. package/dist-types/utils/constants/version.d.ts.map +1 -1
  44. package/dist-types/utils/retry/linear-retry-strategy/linear-retry-strategy.d.ts +10 -0
  45. package/dist-types/utils/retry/linear-retry-strategy/linear-retry-strategy.d.ts.map +1 -0
  46. package/dist-types/utils/retry/linear-retry-strategy/linear-retry-strategy.test.d.ts +2 -0
  47. package/dist-types/utils/retry/linear-retry-strategy/linear-retry-strategy.test.d.ts.map +1 -0
  48. package/dist-types/utils/retry/retry-presets/retry-presets.d.ts +13 -1
  49. package/dist-types/utils/retry/retry-presets/retry-presets.d.ts.map +1 -1
  50. package/dist-types/utils/serdes/filesystem-serdes.d.ts +119 -0
  51. package/dist-types/utils/serdes/filesystem-serdes.d.ts.map +1 -0
  52. package/dist-types/utils/serdes/filesystem-serdes.test.d.ts +2 -0
  53. package/dist-types/utils/serdes/filesystem-serdes.test.d.ts.map +1 -0
  54. package/dist-types/utils/serdes/preview.d.ts +96 -0
  55. package/dist-types/utils/serdes/preview.d.ts.map +1 -0
  56. package/dist-types/utils/serdes/serdes.d.ts +29 -0
  57. package/dist-types/utils/serdes/serdes.d.ts.map +1 -1
  58. package/dist-types/utils/with-retry/index.d.ts +188 -0
  59. package/dist-types/utils/with-retry/index.d.ts.map +1 -0
  60. package/dist-types/utils/with-retry/index.test.d.ts +2 -0
  61. package/dist-types/utils/with-retry/index.test.d.ts.map +1 -0
  62. package/dist-types/with-durable-execution.d.ts.map +1 -1
  63. package/package.json +3 -3
@@ -1,14 +1,3 @@
1
- /**
2
- * SDK metadata injected by Rollup at build time from package.json.
3
- *
4
- * At build time, Rollup replaces process.env.NPM_PACKAGE_NAME and
5
- * process.env.NPM_PACKAGE_VERSION with actual values from package.json.
6
- *
7
- * Defaults are provided for test environments where Rollup doesn't run
8
- * and process.env values are undefined.
9
- *
10
- * @internal
11
- */
12
- export declare const SDK_NAME: string;
1
+ export declare const SDK_NAME = "aws-durable-execution-sdk-js";
13
2
  export declare const SDK_VERSION: string;
14
3
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../src/utils/constants/version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,QAAQ,QAC4C,CAAC;AAClE,eAAO,MAAM,WAAW,QAA6C,CAAC"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../src/utils/constants/version.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,QAAQ,iCAAiC,CAAC;AAEvD,eAAO,MAAM,WAAW,QAET,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { RetryDecision } from "../../../types";
2
+ /**
3
+ * Creates a linear backoff retry strategy
4
+ * @param maxAttempts - Maximum number of attempts (default: 6)
5
+ * @param initialDelay - Initial delay in seconds (default: 1)
6
+ * @param increment - Linear increment per attempt in seconds (default: 1)
7
+ * @returns Retry strategy with linear backoff
8
+ */
9
+ export declare const createLinearRetryStrategy: (maxAttempts?: number, initialDelay?: number, increment?: number) => (error: Error, attemptsMade: number) => RetryDecision;
10
+ //# sourceMappingURL=linear-retry-strategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linear-retry-strategy.d.ts","sourceRoot":"","sources":["../../../../src/utils/retry/linear-retry-strategy/linear-retry-strategy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,GACpC,cAAa,MAAU,EACvB,eAAc,MAAU,EACxB,YAAW,MAAU,MAEb,OAAO,KAAK,EAAE,cAAc,MAAM,KAAG,aAU9C,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=linear-retry-strategy.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linear-retry-strategy.test.d.ts","sourceRoot":"","sources":["../../../../src/utils/retry/linear-retry-strategy/linear-retry-strategy.test.ts"],"names":[],"mappings":""}
@@ -2,11 +2,16 @@
2
2
  * Pre-configured retry strategies for common use cases
3
3
  * @example
4
4
  * ```typescript
5
- * // Use default retry preset (3 attempts with exponential backoff)
5
+ * // Use default retry preset (6 attempts with exponential backoff)
6
6
  * await context.step('my-step', async () => {
7
7
  * return await someOperation();
8
8
  * }, { retryStrategy: retryPresets.default });
9
9
  *
10
+ * // Use linear retry preset (1s, 2s, 3s, 4s, 5s delays)
11
+ * await context.step('linear-step', async () => {
12
+ * return await someOperation();
13
+ * }, { retryStrategy: retryPresets.linear });
14
+ *
10
15
  * // Use no-retry preset (fail immediately on error)
11
16
  * await context.step('critical-step', async () => {
12
17
  * return await criticalOperation();
@@ -26,6 +31,13 @@ export declare const retryPresets: {
26
31
  * - Total max wait time less than 150 seconds (2:30)
27
32
  */
28
33
  default: (error: Error, attemptsMade: number) => import("../../..").RetryDecision;
34
+ /**
35
+ * Linear retry strategy with fixed increment
36
+ * - 6 total attempts (1 initial + 5 retries)
37
+ * - Delays: 1s, 2s, 3s, 4s, 5s
38
+ * - Total max wait time: 15 seconds
39
+ */
40
+ linear: (error: Error, attemptsMade: number) => import("../../..").RetryDecision;
29
41
  /**
30
42
  * No retry strategy - fails immediately on first error
31
43
  * - 1 total attempt (no retries)
@@ -1 +1 @@
1
- {"version":3,"file":"retry-presets.d.ts","sourceRoot":"","sources":["../../../../src/utils/retry/retry-presets/retry-presets.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,YAAY;IACvB;;;;;;;;OAQG;;IASH;;;OAGG;;CAIJ,CAAC"}
1
+ {"version":3,"file":"retry-presets.d.ts","sourceRoot":"","sources":["../../../../src/utils/retry/retry-presets/retry-presets.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,YAAY;IACvB;;;;;;;;OAQG;;IASH;;;;;OAKG;;IAGH;;;OAGG;;CAIJ,CAAC"}
@@ -0,0 +1,119 @@
1
+ import { AnySerdes } from "./serdes";
2
+ export { FieldMatchMode, PreviewMode, PreviewField, PreviewConfig, buildPreview, } from "./preview";
3
+ /**
4
+ * Controls when data is written to the filesystem.
5
+ *
6
+ * - `ALWAYS`: Every value is written to a file; the checkpoint stores only a file pointer.
7
+ * Best for consistently large payloads or when you want predictable checkpoint sizes.
8
+ *
9
+ * - `OVERFLOW`: Data is written inline (as JSON) unless it exceeds the durable function
10
+ * checkpoint size limit (~256KB), in which case it overflows to a file.
11
+ * Best for mixed workloads where most payloads are small.
12
+ *
13
+ * @public
14
+ */
15
+ export declare enum FileSystemSerdesMode {
16
+ ALWAYS = "ALWAYS",
17
+ OVERFLOW = "OVERFLOW"
18
+ }
19
+ /**
20
+ * Configuration options for {@link createFileSystemSerdes}.
21
+ *
22
+ * @public
23
+ */
24
+ export interface FileSystemSerdesConfig {
25
+ /**
26
+ * Controls when data is written to the filesystem.
27
+ * @defaultValue `FileSystemSerdesMode.ALWAYS`
28
+ */
29
+ storageMode?: FileSystemSerdesMode;
30
+ /**
31
+ * Optional function that generates a preview object from the value.
32
+ * When provided, the preview is stored inline in the checkpoint envelope
33
+ * alongside the file pointer, making data visible in the console and API
34
+ * without reading the full file.
35
+ *
36
+ * Use {@link buildPreview} with a {@link PreviewConfig} for the built-in
37
+ * field selection logic, or provide your own implementation.
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * // Using the built-in buildPreview helper
42
+ * createFileSystemSerdes("/mnt/s3", {
43
+ * generatePreview: (value) => buildPreview(value, {
44
+ * mode: PreviewMode.EXCLUDE_ALL,
45
+ * include: [{ name: "id" }, { name: "status" }],
46
+ * mask: [{ name: "email" }],
47
+ * }),
48
+ * });
49
+ *
50
+ * // Custom implementation
51
+ * createFileSystemSerdes("/mnt/s3", {
52
+ * generatePreview: (value) => ({
53
+ * id: (value as any).id,
54
+ * summary: `Order ${(value as any).id}`,
55
+ * }),
56
+ * });
57
+ * ```
58
+ */
59
+ generatePreview?: (value: unknown) => Record<string, unknown> | undefined;
60
+ }
61
+ /**
62
+ * Creates a Serdes that stores serialized values on a durable filesystem.
63
+ *
64
+ * **⚠️ WARNING: Do NOT use with Lambda's ephemeral `/tmp` storage.**
65
+ * Lambda's `/tmp` filesystem is local to a single execution environment and is
66
+ * not shared across invocations or function instances. On replay, a different
67
+ * execution environment may be used and the file will not be found, causing
68
+ * deserialization to fail.
69
+ *
70
+ * **Use only with a durable, shared filesystem such as:**
71
+ * - **Amazon S3 Files** — mount an S3 bucket as a filesystem via the Lambda console or IaC
72
+ * - **Amazon EFS** — mount an EFS file system to your Lambda function
73
+ *
74
+ * Both options provide persistence across invocations and are accessible from
75
+ * multiple concurrent function instances, which is required for correct replay behavior.
76
+ *
77
+ * The checkpoint stores a JSON envelope that is either:
78
+ * - `{"data":"<inline JSON>"}` — value stored inline (OVERFLOW mode, under threshold)
79
+ * - `{"file":"<path>"}` — value stored in a file
80
+ * - `{"file":"<path>","preview":{...}}` — file pointer with inline preview (when preview is configured)
81
+ *
82
+ * @param basePath - Directory path where data files will be stored (e.g. `/mnt/s3` for S3 Files, `/mnt/efs` for EFS)
83
+ * @param config - Optional configuration options
84
+ * @returns A Serdes that reads/writes JSON files under basePath
85
+ *
86
+ * @example
87
+ * ```typescript
88
+ * // Always write to S3 Files mount (default)
89
+ * context.configureSerdes({
90
+ * defaultSerdes: createFileSystemSerdes("/mnt/s3"),
91
+ * });
92
+ *
93
+ * // Only overflow to filesystem when payload exceeds ~256KB
94
+ * context.configureSerdes({
95
+ * defaultSerdes: createFileSystemSerdes("/mnt/s3", { storageMode: FileSystemSerdesMode.OVERFLOW }),
96
+ * });
97
+ *
98
+ * // With preview: show id and masked email in checkpoint
99
+ * context.configureSerdes({
100
+ * defaultSerdes: createFileSystemSerdes("/mnt/s3", {
101
+ * generatePreview: (value) => buildPreview(value, {
102
+ * mode: PreviewMode.EXCLUDE_ALL,
103
+ * include: [{ name: "id" }, { name: "status" }],
104
+ * mask: [{ name: "email" }],
105
+ * }),
106
+ * }),
107
+ * });
108
+ * ```
109
+ *
110
+ * Limitations:
111
+ * - Field names containing dots are not supported in preview field selectors.
112
+ * A dot in a field name is indistinguishable from a path separator.
113
+ * - Array structure is not preserved in preview output — fields from array
114
+ * elements are merged into a plain object at the array's path.
115
+ *
116
+ * @public
117
+ */
118
+ export declare function createFileSystemSerdes(basePath: string, config?: FileSystemSerdesConfig): AnySerdes;
119
+ //# sourceMappingURL=filesystem-serdes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem-serdes.d.ts","sourceRoot":"","sources":["../../../src/utils/serdes/filesystem-serdes.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,SAAS,EAAE,MAAM,UAAU,CAAC;AAEpD,OAAO,EACL,cAAc,EACd,WAAW,EACX,YAAY,EACZ,aAAa,EACb,YAAY,GACb,MAAM,WAAW,CAAC;AAKnB;;;;;;;;;;;GAWG;AACH,oBAAY,oBAAoB;IAC9B,MAAM,WAAW;IACjB,QAAQ,aAAa;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;CAC3E;AAoBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,sBAA2B,GAClC,SAAS,CAiDX"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=filesystem-serdes.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem-serdes.test.d.ts","sourceRoot":"","sources":["../../../src/utils/serdes/filesystem-serdes.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Controls whether a preview field is matched by name anywhere in the object
3
+ * tree, or by exact dot-notation path from the root.
4
+ *
5
+ * @public
6
+ */
7
+ export declare enum FieldMatchMode {
8
+ /** Match the field name at any depth in the object tree (default). */
9
+ ANYWHERE = "ANYWHERE",
10
+ /**
11
+ * Match by exact dot-notation path from root.
12
+ * A single segment (e.g. `"email"`) matches only the root-level field.
13
+ * A dotted path (e.g. `"user.email"`) matches that exact nested location.
14
+ */
15
+ PATH = "PATH"
16
+ }
17
+ /**
18
+ * Controls which fields are included in the preview by default.
19
+ *
20
+ * @public
21
+ */
22
+ export declare enum PreviewMode {
23
+ /** Include all fields, then apply `exclude` and `mask` rules. */
24
+ INCLUDE_ALL = "INCLUDE_ALL",
25
+ /** Exclude all fields, then apply `include` and `mask` rules. */
26
+ EXCLUDE_ALL = "EXCLUDE_ALL"
27
+ }
28
+ /**
29
+ * A field selector used in preview include/exclude/mask lists.
30
+ *
31
+ * @public
32
+ */
33
+ export interface PreviewField {
34
+ /** Field name or dot-notation path. */
35
+ name: string;
36
+ /** How to match the field. Defaults to `FieldMatchMode.ANYWHERE`. */
37
+ match?: FieldMatchMode;
38
+ }
39
+ /**
40
+ * Configuration for {@link buildPreview}.
41
+ *
42
+ * @public
43
+ */
44
+ export interface PreviewConfig {
45
+ /** Whether to start with all fields included or all excluded. */
46
+ mode: PreviewMode;
47
+ /** Fields to include (used with `EXCLUDE_ALL` mode, or to override `INCLUDE_ALL`). */
48
+ include?: PreviewField[];
49
+ /** Fields to exclude (used with `INCLUDE_ALL` mode, or to override `EXCLUDE_ALL`). */
50
+ exclude?: PreviewField[];
51
+ /** Fields to mask — if visible, their value is replaced with `maskString`. */
52
+ mask?: PreviewField[];
53
+ /**
54
+ * String used to replace masked field values.
55
+ * @defaultValue `"***"`
56
+ */
57
+ maskString?: string;
58
+ /**
59
+ * Maximum size in bytes for the preview object (JSON-serialized).
60
+ * Fields are added until this limit is reached.
61
+ * @defaultValue `4096`
62
+ */
63
+ maxPreviewBytes?: number;
64
+ }
65
+ /**
66
+ * Builds a preview object from `value` according to `config`.
67
+ *
68
+ * Traverses the object tree and collects fields based on the include/exclude/mask
69
+ * rules in `config`. The result is a nested object mirroring the original structure,
70
+ * capped at `config.maxPreviewBytes` (default 4096 bytes).
71
+ *
72
+ * Priority rules:
73
+ * - `exclude` always wins — excluded fields are never shown, even if in `mask`
74
+ * - `mask` implies visibility — masked fields are shown (with `maskString`) unless excluded
75
+ *
76
+ * Limitations:
77
+ * - Field names containing dots are not supported (indistinguishable from path separators)
78
+ * - Array structure is not preserved — fields from array elements are merged into a plain object
79
+ * - When array elements have heterogeneous shapes at the same field path, later elements
80
+ * overwrite earlier primitives in the preview (e.g. `[{ user: "arb" }, { user: { email: "x" } }]`
81
+ * produces `{ user: { email: "x" } }` — `"arb"` is lost)
82
+ *
83
+ * @example
84
+ * ```typescript
85
+ * const preview = buildPreview(order, {
86
+ * mode: PreviewMode.EXCLUDE_ALL,
87
+ * include: [{ name: "id" }, { name: "status" }],
88
+ * mask: [{ name: "email" }],
89
+ * });
90
+ * // { id: "order-123", status: "pending", user: { email: "***" } }
91
+ * ```
92
+ *
93
+ * @public
94
+ */
95
+ export declare function buildPreview(value: any, config: PreviewConfig): Record<string, unknown> | undefined;
96
+ //# sourceMappingURL=preview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../../src/utils/serdes/preview.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,oBAAY,cAAc;IACxB,sEAAsE;IACtE,QAAQ,aAAa;IACrB;;;;OAIG;IACH,IAAI,SAAS;CACd;AAED;;;;GAIG;AACH,oBAAY,WAAW;IACrB,iEAAiE;IACjE,WAAW,gBAAgB;IAC3B,iEAAiE;IACjE,WAAW,gBAAgB;CAC5B;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,KAAK,CAAC,EAAE,cAAc,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,iEAAiE;IACjE,IAAI,EAAE,WAAW,CAAC;IAClB,sFAAsF;IACtF,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,sFAAsF;IACtF,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,8EAA8E;IAC9E,IAAI,CAAC,EAAE,YAAY,EAAE,CAAC;IACtB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAeD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,GAAG,EACV,MAAM,EAAE,aAAa,GACpB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAkFrC"}
@@ -35,6 +35,35 @@ export interface Serdes<T> {
35
35
  */
36
36
  deserialize: (data: string | undefined, context: SerdesContext) => Promise<T | undefined>;
37
37
  }
38
+ /**
39
+ * Serdes typed for arbitrary values. Used internally where the concrete type is unknown.
40
+ * @internal
41
+ */
42
+ export type AnySerdes = Serdes<any>;
43
+ /**
44
+ * Deserialize-only Serdes typed for arbitrary values. Used for callback deserializers.
45
+ * @internal
46
+ */
47
+ export type AnySerdesDeserializer = Pick<AnySerdes, "deserialize">;
48
+ /**
49
+ * Configuration for default serdes behavior on a DurableContext.
50
+ *
51
+ * @public
52
+ */
53
+ export interface SerdesConfig {
54
+ /**
55
+ * Default serdes used for step, runInChildContext, invoke, and waitForCondition results.
56
+ * Falls back to the built-in JSON serdes if not provided.
57
+ */
58
+ defaultSerdes?: AnySerdes;
59
+ /**
60
+ * Default deserializer used for createCallback and waitForCallback results.
61
+ * If not provided, falls back to the built-in passthrough (raw string) deserializer,
62
+ * regardless of whether defaultSerdes is set.
63
+ * Must be set explicitly to use a custom deserializer for callbacks.
64
+ */
65
+ defaultCallbackDeserializer?: AnySerdesDeserializer;
66
+ }
38
67
  /**
39
68
  * Default Serdes implementation using JSON.stringify and JSON.parse
40
69
  * Wrapped in Promise.resolve() to maintain async interface compatibility
@@ -1 +1 @@
1
- {"version":3,"file":"serdes.d.ts","sourceRoot":"","sources":["../../../src/utils/serdes/serdes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB;;;;;OAKG;IACH,SAAS,EAAE,CACT,KAAK,EAAE,CAAC,GAAG,SAAS,EACpB,OAAO,EAAE,aAAa,KACnB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAEjC;;;;;OAKG;IACH,WAAW,EAAE,CACX,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,EAAE,aAAa,KACnB,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;CAC7B;AAED;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,GAAG,CAYrC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,EAChD,GAAG,EAAE,UAAU,CAAC,GACf,MAAM,CAAC,CAAC,CAAC,CAeX;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,MAAM,EACzD,GAAG,EAAE,UAAU,CAAC,EAChB,SAAS,EAAE,MAAM,EAAE,GAClB,MAAM,CAAC,CAAC,CAAC,CA2CX"}
1
+ {"version":3,"file":"serdes.d.ts","sourceRoot":"","sources":["../../../src/utils/serdes/serdes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB;;;;;OAKG;IACH,SAAS,EAAE,CACT,KAAK,EAAE,CAAC,GAAG,SAAS,EACpB,OAAO,EAAE,aAAa,KACnB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAEjC;;;;;OAKG;IACH,WAAW,EAAE,CACX,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,EAAE,aAAa,KACnB,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;CAC7B;AAED;;;GAGG;AAEH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;AAEpC;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;AAEnE;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,aAAa,CAAC,EAAE,SAAS,CAAC;IAE1B;;;;;OAKG;IACH,2BAA2B,CAAC,EAAE,qBAAqB,CAAC;CACrD;AAED;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,GAAG,CAYrC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,EAChD,GAAG,EAAE,UAAU,CAAC,GACf,MAAM,CAAC,CAAC,CAAC,CAeX;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,MAAM,EACzD,GAAG,EAAE,UAAU,CAAC,EAChB,SAAS,EAAE,MAAM,EAAE,GAClB,MAAM,CAAC,CAAC,CAAC,CA2CX"}
@@ -0,0 +1,188 @@
1
+ import { DurableContext } from "../../types/durable-context";
2
+ import { RetryDecision } from "../../types";
3
+ import { ChildConfig } from "../../types/child-context";
4
+ /**
5
+ * Configuration for {@link withRetry}.
6
+ *
7
+ * @typeParam T - The resolved value type of a successful attempt. Used to
8
+ * type {@link WithRetryConfig.childContextConfig}. Inferred automatically
9
+ * from the function passed to {@link withRetry}; callers rarely need to
10
+ * specify it explicitly.
11
+ *
12
+ * @public
13
+ */
14
+ export interface WithRetryConfig<T> {
15
+ /**
16
+ * Strategy for retrying failed attempts. Uses the same signature as
17
+ * {@link StepConfig.retryStrategy}, so values produced by
18
+ * {@link createRetryStrategy} or entries of {@link retryPresets} can be
19
+ * passed directly.
20
+ *
21
+ * @param error - The error thrown by the most recent attempt.
22
+ * @param attemptCount - The 1-based attempt number that just failed.
23
+ * @returns A {@link RetryDecision} describing whether to retry and the
24
+ * backoff delay to use before the next attempt.
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * retryStrategy: (error, attempt) => ({
29
+ * shouldRetry: attempt < 3,
30
+ * delay: { seconds: 2 ** attempt },
31
+ * })
32
+ * ```
33
+ */
34
+ retryStrategy: (error: Error, attemptCount: number) => RetryDecision;
35
+ /**
36
+ * Wrap the retry loop (attempts + backoff waits) in `runInChildContext`
37
+ * so attempts are grouped under a single operation in the execution
38
+ * history. When a `name` is provided it's used as the child context's
39
+ * name; otherwise the child context is anonymous.
40
+ *
41
+ * @remarks
42
+ * Changing this flag changes the shape of thrown errors:
43
+ * - When `true` (default), a final failure is rethrown as a
44
+ * {@link ChildContextError} that wraps the original error on its `cause`
45
+ * property (standard `runInChildContext` behavior).
46
+ * - When `false`, the original error from the final failed attempt is
47
+ * rethrown unchanged.
48
+ *
49
+ * Code that uses `instanceof` to branch on error type should account for
50
+ * this, or always inspect `error.cause`.
51
+ *
52
+ * @defaultValue true
53
+ */
54
+ wrapWithRunInChildContext?: boolean;
55
+ /**
56
+ * Optional {@link ChildConfig} forwarded to the wrapping
57
+ * `context.runInChildContext` call (e.g. `serdes`, `subType`,
58
+ * `errorMapper`, `virtualContext`).
59
+ *
60
+ * @remarks
61
+ * Ignored when {@link WithRetryConfig.wrapWithRunInChildContext} is
62
+ * `false`.
63
+ *
64
+ * If `errorMapper` is provided it runs on errors produced by the child
65
+ * context (i.e. after retries are exhausted), not on per-attempt errors
66
+ * handed to {@link WithRetryConfig.retryStrategy}.
67
+ */
68
+ childContextConfig?: ChildConfig<T>;
69
+ }
70
+ /**
71
+ * A function executed by {@link withRetry} on each attempt.
72
+ *
73
+ * @remarks
74
+ * The body can contain any chunk of durable-execution logic — multiple
75
+ * steps, waits, callbacks, invokes, etc. — not just a single durable
76
+ * operation.
77
+ *
78
+ * @typeParam T - The resolved value type of a successful attempt.
79
+ * @param context - The {@link DurableContext} to use for durable operations.
80
+ * When {@link WithRetryConfig.wrapWithRunInChildContext} is enabled this is
81
+ * the child context.
82
+ * @param attempt - The 1-based attempt number. Provided as metadata; useful
83
+ * for logging or for incorporating into operation names to improve execution
84
+ * history readability. Not required for correctness — the SDK disambiguates
85
+ * operations by call-site position.
86
+ * @returns A promise for the successful result. If it rejects, the error is
87
+ * passed to {@link WithRetryConfig.retryStrategy} to decide whether to
88
+ * retry.
89
+ *
90
+ * @public
91
+ */
92
+ export type RetryableFunc<T> = (context: DurableContext, attempt: number) => Promise<T>;
93
+ /**
94
+ * Runs a chunk of durable-execution logic with retries. Semantically a
95
+ * `runInChildContext` with a retry policy wrapped around it — on failure the
96
+ * whole function body is re-run from the beginning with configurable
97
+ * backoff, using the same `retryStrategy` shape as {@link StepConfig}.
98
+ *
99
+ * @remarks
100
+ * Unlike `context.step()`, durable operations such as `waitForCallback` and
101
+ * `invoke` cannot be nested inside a step. `withRetry` runs the function at
102
+ * the top level and uses `context.wait` between attempts for backoff. By
103
+ * default the whole loop is wrapped in `context.runInChildContext` for
104
+ * isolation (opt out with `wrapWithRunInChildContext: false`); the child
105
+ * context is named when `name` is provided and anonymous otherwise.
106
+ *
107
+ * The function body can contain multiple durable operations — this is
108
+ * effectively "retry this block of logic," not "retry one operation."
109
+ *
110
+ * Because the SDK identifies durable operations by call-site position,
111
+ * unique per-attempt names are not required for correctness. Callers may
112
+ * still incorporate `attempt` into operation names (e.g.
113
+ * "`my-callback-${attempt}`") to make execution history easier to read.
114
+ * Backoff waits are named automatically as `${name}-backoff-${attempt}`
115
+ * when `name` is provided; otherwise they are anonymous.
116
+ *
117
+ * @typeParam T - The resolved value type of a successful attempt.
118
+ * @param context - The parent {@link DurableContext}.
119
+ * @param name - Optional name used for the enclosing child context and
120
+ * backoff wait operations. Omit to run the retry loop directly in `context`.
121
+ * @param func - The function to execute on each attempt.
122
+ * @param config - Retry configuration.
123
+ * @returns The result of the first successful attempt.
124
+ * @throws \{ChildContextError\} When `wrapWithRunInChildContext` is `true`
125
+ * (default) and retries are exhausted or `retryStrategy` returns
126
+ * `shouldRetry: false`. The original error from the final failed attempt is
127
+ * available on the `cause` property.
128
+ * @throws When `wrapWithRunInChildContext` is `false`, the original error
129
+ * from the final failed attempt is rethrown unchanged.
130
+ *
131
+ * @example Named (wrapped in a child context by default)
132
+ * ```typescript
133
+ * import {
134
+ * withRetry,
135
+ * createRetryStrategy,
136
+ * } from "@aws/durable-execution-sdk-js";
137
+ *
138
+ * const decision = await withRetry(
139
+ * context,
140
+ * "approval",
141
+ * (ctx, attempt) =>
142
+ * ctx.waitForCallback(`approval-${attempt}`, submitter, {
143
+ * timeout: { hours: 24 },
144
+ * }),
145
+ * {
146
+ * retryStrategy: createRetryStrategy({
147
+ * maxAttempts: 3,
148
+ * initialDelay: { seconds: 2 },
149
+ * backoffRate: 2,
150
+ * }),
151
+ * },
152
+ * );
153
+ * ```
154
+ *
155
+ * @example Anonymous (no child-context name)
156
+ * ```typescript
157
+ * const result = await withRetry(
158
+ * context,
159
+ * (ctx, attempt) =>
160
+ * ctx.invoke(`charge-${attempt}`, paymentFnArn, { orderId }),
161
+ * {
162
+ * retryStrategy: (_err, attempt) => ({
163
+ * shouldRetry: attempt < 3,
164
+ * delay: { seconds: 1 },
165
+ * }),
166
+ * },
167
+ * );
168
+ * ```
169
+ *
170
+ * @see {@link createRetryStrategy}
171
+ * @see {@link retryPresets}
172
+ * @see {@link StepConfig}
173
+ *
174
+ * @public
175
+ */
176
+ export declare function withRetry<T>(context: DurableContext, name: string, func: RetryableFunc<T>, config: WithRetryConfig<T>): Promise<T>;
177
+ /**
178
+ * Anonymous overload of {@link withRetry}.
179
+ *
180
+ * @remarks
181
+ * Same behavior as the named overload, but the enclosing
182
+ * `runInChildContext` (when `wrapWithRunInChildContext` is enabled) and the
183
+ * backoff waits are anonymous.
184
+ *
185
+ * @public
186
+ */
187
+ export declare function withRetry<T>(context: DurableContext, func: RetryableFunc<T>, config: WithRetryConfig<T>): Promise<T>;
188
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/with-retry/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD;;;;;;;;;GASG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC;;;;;;;;;;;;;;;;;;OAkBG;IACH,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,KAAK,aAAa,CAAC;IAErE;;;;;;;;;;;;;;;;;;OAkBG;IACH,yBAAyB,CAAC,EAAE,OAAO,CAAC;IAEpC;;;;;;;;;;;;OAYG;IACH,kBAAkB,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;CACrC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAC7B,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC,CAAC,CAAC,CAAC;AAEhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkFG;AACH,wBAAgB,SAAS,CAAC,CAAC,EACzB,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,EACtB,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,GACzB,OAAO,CAAC,CAAC,CAAC,CAAC;AACd;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,CAAC,EACzB,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,EACtB,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,GACzB,OAAO,CAAC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../../src/utils/with-retry/index.test.ts"],"names":[],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"with-durable-execution.d.ts","sourceRoot":"","sources":["../src/with-durable-execution.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,aAAa,EAMd,MAAM,SAAS,CAAC;AAKjB,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,EACrB,MAAM,2BAA2B,CAAC;AA8PnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsEG;AACH,eAAO,MAAM,oBAAoB,GAE/B,MAAM,GAAG,GAAG,EAEZ,OAAO,GAAG,GAAG,EACb,OAAO,SAAS,aAAa,GAAG,aAAa,EAE7C,SAAS,uBAAuB,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EAC1D,SAAS,sBAAsB,KAC9B,oBAiBF,CAAC"}
1
+ {"version":3,"file":"with-durable-execution.d.ts","sourceRoot":"","sources":["../src/with-durable-execution.ts"],"names":[],"mappings":"AAYA,OAAO,EACL,aAAa,EAMd,MAAM,SAAS,CAAC;AAKjB,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,EACrB,MAAM,2BAA2B,CAAC;AA8PnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsEG;AACH,eAAO,MAAM,oBAAoB,GAE/B,MAAM,GAAG,GAAG,EAEZ,OAAO,GAAG,GAAG,EACb,OAAO,SAAS,aAAa,GAAG,aAAa,EAE7C,SAAS,uBAAuB,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EAC1D,SAAS,sBAAsB,KAC9B,oBA6BF,CAAC"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@aws/durable-execution-sdk-js",
3
3
  "description": "AWS Durable Execution Language SDK for TypeScript",
4
4
  "license": "Apache-2.0",
5
- "version": "1.1.2",
5
+ "version": "2.0.0-alpha.1",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+ssh://git@github.com/aws/aws-durable-execution-sdk-js.git",
@@ -57,7 +57,7 @@
57
57
  "@typescript-eslint/parser": "^8.25.0",
58
58
  "eslint": "^9.21.0",
59
59
  "eslint-plugin-filename-convention": "file:scripts/eslint-plugin-filename-convention",
60
- "eslint-plugin-tsdoc": "^0.4.0",
60
+ "eslint-plugin-tsdoc": "^0.5.2",
61
61
  "jest": "^29.7.0",
62
62
  "prettier": "^3.5.2",
63
63
  "rimraf": "^5.0.10",
@@ -66,7 +66,7 @@
66
66
  "typescript": "^5.7.3"
67
67
  },
68
68
  "dependencies": {
69
- "@aws-sdk/client-lambda": "^3.943.0"
69
+ "@aws-sdk/client-lambda": "^3.1014.0"
70
70
  },
71
71
  "private": false
72
72
  }