# @aws/durable-execution-sdk-js 中文文档

规范地址：https://npmcn.com/package/%40aws/durable-execution-sdk-js/

版本：3\.0\.0
npm 元数据更新时间：2026-10-26T03:44:04.590Z
中文译文更新时间：2026-11-07T10:12:14.987Z
软件包许可：Apache-2\.0

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40aws/durable-execution-sdk-js
原文对照：https://npmcn.com/package/%40aws/durable-execution-sdk-js/?lang=original
项目主页：https://github.com/aws/aws-durable-execution-sdk-js/tree/main/packages/aws-durable-execution-sdk-js
源码仓库：https://github.com/aws/aws-durable-execution-sdk-js

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：1.7 MB，436 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=22
- 运行依赖：1 个
- 首次发布：2025-11-25T00:23:12.319Z
- 最新版本发布：2026-10-26T03:44:04.235Z
- 近 30 天下载量：3907208（2026-10-08 至 2026-11-06，npm 官方下载统计）
- 已发布版本数：26（近 12 个月 26 个）

## 中文简介

类型脚本的 AWS 持久执行语言 SDK

## 安装

```sh
npm install @aws/durable-execution-sdk-js
```

也可以使用：`pnpm add @aws/durable-execution-sdk-js`、`yarn add @aws/durable-execution-sdk-js`、`bun add @aws/durable-execution-sdk-js`

## README

# JavaScript 的 AWS 持久执行 SDK

TypeScript SDK用于构建状态,长期运行的AWS Lambda功能,具有自动状态持久性,重试逻辑,和工作流程管弦.

## 特征

-   **持久执行**: 自动维持状态,并从检查站恢复
-   **自动检索**: 可配置的重试策略,带有指数后退和焦急
-   **工作流程管弦**: 将复杂的工作流程与步骤、儿童背景和平行执行结合起来
-   **外部一体化**: 等待外部系统的召回
-   **批量操作**: 具有货币控制和完成政策的流程数组
-   **类型安全**: 包含全面类型定义的完整类型脚本支持

## 安装

```bash
npm install @aws/durable-execution-sdk-js
```

## 快速启动

```typescript
import {
  withDurableExecution,
  DurableContext,
} from "@aws/durable-execution-sdk-js";

const handler = async (event: any, context: DurableContext) => {
  // Execute a durable step with automatic retry
  const userData = await context.step("fetch-user", async () =>
    fetchUserFromDB(event.userId),
  );

  // Wait for 5 seconds
  await context.wait({ seconds: 5 });

  // Process data in another step
  const result = await context.step("process-user", async () =>
    processUser(userData),
  );

  return result;
};

export const lambdaHandler = withDurableExecution(handler);
```

## 文档

这个README为SDK的主要功能提供了快速的参考. 详细情况:

-   **[API 参考](https://docs.aws.amazon.com/durable-execution/)** - 附有详细类型定义和操作规格的完整技术参考
-   **[概念和使用案例](https://npmcn.com/package/%40aws/durable-execution-sdk-js/src/documents/CONCEPTS.md)** - 了解重放模式、最佳做法和现实世界的例子,包括GenAI代理、人入工作流程和saga模式
-   **[捐款](https://npmcn.com/package/CONTRIBUTING.md)** - 学习如何为JavaScript的 AWS 持久执行 SDK 做出贡献

## 核心概念

### 持久语句

这个 `DurableContext` 是构建持久工作流程的主要接口。 它提供了执行步骤、等待、援引其他职能和协调平行行动的方法.

### 步骤操作

用自动重试和状态持久性执行原子操作 :

```typescript
// Named step with retry configuration
const result = await context.step(
  "fetch-data",
  async (ctx) => {
    return await fetchFromAPI();
  },
  {
    retryStrategy: (error, attempt) => ({
      shouldRetry: attempt < 3,
      delay: { seconds: Math.pow(2, attempt) },
    }),
  },
);

// Anonymous step
const data = await context.step(async () => processData());
```

**重要**数字 : `step()` 仅用于单一原子操作。 组合多个可持久操作, 使用 `runInChildContext()`。 。 。 .

### 儿童背景

以孤立状态跟踪方式分组多个持久操作 :

```typescript
const orderResult = await context.runInChildContext(
  "process-order",
  async (childCtx) => {
    // Child context has its own step counter and state
    const validated = await childCtx.step("validate", async () =>
      validateOrder(order),
    );
    await childCtx.wait({ seconds: 1 });
    const charged = await childCtx.step("charge", async () =>
      chargePayment(validated),
    );
    return charged;
  },
);
```

### 引用其他函数

调用另一个 AWS Lambda 函数并等待完成 :

```typescript
const result = await context.invoke(
  "process-payment",
  "arn:aws:lambda:us-east-1:123456789012:function:payment-processor",
  { amount: 100, currency: "USD" },
);
```

### 等待操作

在指定期限内暂停执行 :

```typescript
// Wait 30 seconds
await context.wait({ seconds: 30 });

// Named wait for tracking
await context.wait("rate-limit-delay", { seconds: 5 });
```

### 有条件的等待

等待定期检查状态满足条件 :

```typescript
const finalState = await context.waitForCondition(
  "wait-for-job",
  async (currentState, ctx) => {
    const status = await checkJobStatus(currentState.jobId);
    return { ...currentState, status };
  },
  {
    initialState: { jobId: "job-123", status: "pending" },
    waitStrategy: (state, attempt) => {
      if (state.status === "completed") {
        return { shouldContinue: false };
      }
      return {
        shouldContinue: true,
        delay: { seconds: Math.min(attempt * 2, 60) },
      };
    },
  },
);
```

### 外部调用

等待外部系统完成操作 :

```typescript
// Create a callback and send ID to external system
const [callbackPromise, callbackId] = await context.createCallback(
  "external-approval",
  { timeout: { minutes: 3 } },
);

await sendApprovalRequest(callbackId, requestData);
const approvalResult = await callbackPromise;

// Or use waitForCallback with submitter function
const result = await context.waitForCallback(
  "wait-for-webhook",
  async (callbackId, ctx) => {
    await submitToExternalAPI(callbackId);
  },
  { timeout: { minutes: 5 } },
);
```

## 批量操作

### 地图

处理项目阵列,对每个有货币控制的持久操作:

```typescript
const results = await context.map(
  "process-users",
  users,
  async (ctx, user, index) => {
    return await ctx.step(`process-${user.id}`, async () => processUser(user));
  },
  {
    maxConcurrency: 5,
    completionConfig: {
      minSuccessful: 8,
      toleratedFailureCount: 2,
    },
    itemNamer: (user, index) => `User-${user.id}`,
  },
);

// Check results
console.log(
  `Succeeded: ${results.successCount}, Failed: ${results.failureCount}`,
);
results.throwIfError(); // Throws if any failures
```

**说明**数字 : `map()` 在同一 Lambda 范围内,利用儿童背景进行持久行动(步骤、等等)。 它不会产生单独的Lambda功能.

### 平行

执行多个分支,同时进行持久操作:

```typescript
const results = await context.parallel(
  "parallel-tasks",
  [
    { name: "task1", func: async (ctx) => ctx.step(async () => fetchData1()) },
    { name: "task2", func: async (ctx) => ctx.step(async () => fetchData2()) },
    async (ctx) => ctx.step(async () => fetchData3()),
  ],
  {
    maxConcurrency: 2,
    completionConfig: { minSuccessful: 2 },
  },
);
```

**说明**数字 : `parallel()` 在同一 Lambda 引用范围内执行持久操作。 每个分支在自己的儿童背景中运行,都有孤立的状态跟踪.

### 提前完成

A 类 `map()` 或者说 `parallel()` 完成时间很早,在每件物品完成之前,完成规则。 没有 `completionConfig`,规则为故障快取: 第一次故障完成批次. `minSuccessful`, (中文(简体) ), `toleratedFailureCount`, (中文(简体) ), `toleratedFailurePercentage` 财务报告和审定财务报表 `shouldComplete` 设置其他规则。 设置其中的任何一个替换故障快取 .

批量检查它的规则 每次一个物品的结果到达它。 一旦遵守规则,其余物品即被废弃:

-   正在运行的项目报告为 `STARTED`。不计为 `successCount` 或者说 `failureCount`。 。 。 .
-   由于 `maxConcurrency`,不出现在 `all`。 。 。 .
-   该批货物不等待被废弃的物品,也不阻止它们。 批次上下文完成后,物品的出站点即被撤销. 被遗弃的物品只有在等待停放检查站时才停止。 在此之前,它的代码可以在引用活动时持续运行,它的副作用可能发生. 没有什么等待它, 所以引用可以先结束:
    -   引用激活时, 函数运行的一步会持续运行 。 它不能保证完成。 如果在批次上下文后完成,则其结果不作记录.
    -   一个新的 `step` 默认值 `StepSemantics.AtLeastOncePerRetry` 运行过一次功能,历史没有记录。 一个新的 `waitForCondition` 运行过一次检查功能。 东西就停了.
    -   `runInChildContext` 不等待自己的检查站。 因此它的功能运行,内部的操作遵循了这些规则.
    -   一个新的 `wait`, (中文(简体) ), `invoke`, (中文(简体) ), `createCallback`, (中文(简体) ), `waitForCallback`,或与 `StepSemantics.AtMostOncePerRetry` 在项目生效前停止。 "新"指批次上下文完成后项目开始. 较早开始的一次行动可能已经记录其开始和生效.

接下来会发生什么取决于 处理器在批次后所做的:

-   如果处理器返回,引用可以结束,而被废弃的代码仍然运行. 那密码不能保证完成.
-   如果操作者等待, 例如在一个 `wait` 或召回,在放弃步骤函数时,援引不能中止,或 `waitForCondition` 检查仍在运行中 。 这种行动在功能返回和关闭的检查站解除之前,即为运行。 因此一个缓慢被放弃的功能使引用活动得以进行,这增加了其持续时间和成本.

被废弃的物品可以在批次上下文完成前记录其结果. 这包括一个在完成批次的项目之前记录了结果的项目,但其结果后来到达了批次。 处决历史显示其儿童背景 `SUCCEEDED` 或者说 `FAILED`,则 `BatchResult` 报告为: `STARTED`与 `NestingType.FLAT`,项目没有儿童背景,历史显示它的运作.

处理器只接收 `BatchResult`重放返回相同的已完成项目和相同的 `completionReason`。重放可以省略 `STARTED` 项,因此 `started()`, (中文(简体) ), `startedCount` 财务报告和审定财务报表 `totalCount` 可以在重播后有所不同。 因此,根据已完成的项目作出决定,不核对 `BatchResult` 与处决历史.

要得到每个项目的结果,使用一个不能提前完成的规则. 设定 `toleratedFailurePercentage: 100`,然后离开 `minSuccessful`, (中文(简体) ), `toleratedFailureCount` 财务报告和审定财务报表 `shouldComplete` 未设. 然后,批量等待每一个项目。 失败的项目出现在 `failed()`。电话没有发出,所以打电话 `throwIfError()` 如果失败必须阻止处理者:

```typescript
const results = await context.map("process-all", items, processItem, {
  completionConfig: { toleratedFailurePercentage: 100 },
});
const failures = results.failed(); // every failed item, with its error
```

### 承诺组合者

用于快速、模拟操作(使用) `map()` 或者说 `parallel()` 长期作业:

```typescript
// Wait for all promises
const [user, posts, comments] = await context.promise.all([
  fetchUser(userId),
  fetchPosts(userId),
  fetchComments(userId),
]);

// Race promises
const fastest = await context.promise.race([
  fetchFromPrimary(),
  fetchFromSecondary(),
]);

// Wait for first success
const result = await context.promise.any([
  fetchFromSource1(),
  fetchFromSource2(),
  fetchFromSource3(),
]);

// Wait for all to settle
const results = await context.promise.allSettled([operation1(), operation2()]);
```

**说明**:承诺协调人接受已经执行的承诺,不能提供货币控制或持久性。 使用 `map()` 或者说 `parallel()` 用于持久,有控制的处决.

## 操作子类型

`runInChildContext`, (中文(简体) ), `step`,以及 `createCallback` 接受一个 `subType` 选项。 构成多个操作的函数可以使用它来标记其部件. SDK在检查站中记录了子类型并传递给插件. 因此,执行历史和插件可以过滤这些部件而不解析名称.

```typescript
ctx.runInChildContext(
  name,
  async (child) => {
    const receipt = await child.step("charge", async () => charge(orderId), {
      subType: "OrderCharge",
    });
    await child.step("notify", async () => notify(receipt), {
      subType: "OrderNotify",
    });
    return receipt;
  },
  { subType: "ChargeAndNotify" },
);
```

服务接受1至32个字符 `[a-zA-Z0-9-_]`。空字符串选择默认子类型,例如 `Step` 或者说 `Callback`。重放时将子类型与检查站进行比较。 所以,改变一个子类型 是一种突破性的改变 在飞行中处决.

[`@aws/durable-execution-sdk-js-extras`](https://npmcn.com/package/%40aws/aws-durable-execution-sdk-js-extras) 以这种方式建造的现成作业,例如 `microvm`。 。 。 .

## 配置

### 动态仪器插件

仪器插件可以在 Lambda 冷起步时不导入 在功能的文物。 在函数或函数中安装一个提供者软件包 Lambda 层,然后设置一个命令的包或模块规格列表:

```text
DURABLE_EXECUTION_PLUGINS=@example/durable-otel,@example/durable-audit/provider
```

SDK 导入每个模块一次 `withDurableExecution(...)` 初始化 包裹的处理器。 未设置或空白变量保留了已有的 行为 插件通过 `DurableExecutionConfig.plugins` 首先运行在 它们的配置顺序; 环境选择的插件按照列出的顺序遵循 内 `DURABLE_EXECUTION_PLUGINS`两种来源都是添加剂,包括: 创建相同的插件类型.

提供者模块导出一个命名的工厂 `durableExecutionPluginProvider`A级 工厂是一个带有 `createPlugin(info)` 方法; 一个空函数不是 一并被拒绝。 SDK电话 `createPlugin` 一次引用,与此 引用 `InvocationInfo`,所以它返回的例子 正好服务于一个 援引:

```typescript
import type {
  DurableInstrumentationPlugin,
  DurableInstrumentationPluginFactory,
} from "@aws/durable-execution-sdk-js";

class AuditPlugin implements DurableInstrumentationPlugin {
  constructor(
    private readonly exporter: Exporter,
    private readonly executionArn: string,
  ) {}
  // Implement the lifecycle hooks needed by this plugin.
}

// Built once for the execution environment and shared by every instance.
const exporter = new Exporter();

export const durableExecutionPluginProvider: DurableInstrumentationPluginFactory<AuditPlugin> =
  {
    createPlugin: (info) => new AuditPlugin(exporter, info.executionArn),
  };
```

因为一个实例在引用返回时被放弃,所以插件从来没有 通过执行 ARN 到密钥执行状态, 以及两个执行状态 在一个执行环境中 同时不能观察对方的状态. 属于执行环境的国家——出口国、追踪国 供货商,一个调度员——如上所述,属于厂外.

模块指定符必须通过普通应用模块解决 解析或节点.js模块路径。 对于Lambda层,包装提供者和 其附属关系 `nodejs/node_modules`数字 :

```text
plugin-layer.zip
`-- nodejs
    `-- node_modules
        `-- @example
            `-- durable-audit
```

配置不当, 缺少模块或导出, a `durableExecutionPluginProvider` 无 `createPlugin` 方法和条目 `DurableExecutionConfig.plugins` 报告为: `PluginLoadError` 执行状态读取前失败 —— 两个来源由相同的检查 规则,因为一个条目没有 `createPlugin` 无法生成插件 。 A 类 `createPlugin` 当它运行时扔出,或返回的任何东西, 都象 任何其它插件失败: 该插件会排出引用和执行 不受影响.

### 仪器操作状态和出错

使用 `OperationInfo.status` 以识别终端操作状态,例如 `FAILED`, (中文(简体) ), `CANCELLED`, (中文(简体) ), `TIMED_OUT`,以及 `STOPPED`。 。 。 . `OperationInfo.error` 包含可选 错误细节; 操作失败 `error === undefined`,包括 重放和 `onOperationChange` 元数据。 缺少或空的检查出错数据 不创建错误。 应用的部分细节,包括明确为空 字符串或空堆栈跟踪,仍然可用.

这也适用于 API-v1 插件: 只使用存在 `error` 因为它的故障信号应该检查 `status` 换句话说 对于一个尝试端钩, 使用情况 `AttemptEndInfo.outcome` 以确定该尝试是否失败。 一个外部 没有错误细节的调回失败仍然拒绝调回承诺 保留其失败的运行状态; 可选的仪器细节没有 改变呼叫者的结果 或坚持状态.

### 重试策略

自定义重试策略 :

```typescript
await context.step("custom-retry", async () => riskyOperation(), {
  retryStrategy: (error, attempt) => ({
    shouldRetry: attempt < 5 && error.message.includes("timeout"),
    delay: { seconds: attempt * 2 },
  }),
});
```

### 步骤语义

控制执行保证:

```typescript
import { StepSemantics } from "@aws/durable-execution-sdk-js";

// At-least-once per retry (default)
await context.step("retriable-operation", async () => sendNotification(), {
  semantics: StepSemantics.AtLeastOncePerRetry,
});

// At-most-once per retry
await context.step("idempotent-operation", async () => updateDatabase(), {
  semantics: StepSemantics.AtMostOncePerRetry,
});
```

**重要**: 这些语义应用 _每次重试_,不是每个总体执行:

-   **AtLEastOncePertrich 重写时**: 该步骤将在每次重试时至少执行一次 。 如果该步骤成功但检查站失败(如沙盒崩溃),该步骤将在重放时重新执行.
-   **在最旧的回收站**: 该步骤每次重试最多一次执行. 执行前会设置一个检查点,因此如果在检查点之后但步骤完成前发生故障,在重放时会跳过之前的尝试.

**一步步实现最高一等语义**,使用自定义重试策略:

```typescript
await context.step(
  "truly-once-only",
  async () => callThatCannotTolerateDuplicates(),
  {
    semantics: StepSemantics.AtMostOncePerRetry,
    retryStrategy: () => ({ shouldRetry: false }), // No retries
  },
);
```

没有这个,一个步骤使用 `AtMostOncePerRetry` 已启用的重试仍然可以在不同的重试尝试中执行多次 .

### 抖动策略

防止雷鸣群:

```typescript
import {
  JitterStrategy,
  createRetryStrategy,
} from "@aws/durable-execution-sdk-js";

const retryStrategy = createRetryStrategy({
  maxAttempts: 5,
  initialDelay: { seconds: 1 },
  maxDelay: { seconds: 60 },
  exponentialDelayFactor: 2,
  jitterStrategy: JitterStrategy.FULL,
});
```

### 自定义运输

默认SDK与Lambda持久行刑API会谈. 你可以换了 通过实施 `DurableExecutionClient`,它有两个操作 名称中无 AWS 类型 :

```typescript
import {
  CheckpointDurableExecutionRequest,
  CheckpointDurableExecutionResponse,
  DurableExecutionClient,
  DurableExecutionClientError,
  DurableExecutionClientErrorScope,
  GetDurableExecutionStateRequest,
  GetDurableExecutionStateResponse,
  withDurableExecution,
} from "@aws/durable-execution-sdk-js";

class HttpDurableExecutionClient implements DurableExecutionClient {
  constructor(private readonly endpoint: string) {}

  async getExecutionState(
    params: GetDurableExecutionStateRequest,
  ): Promise<GetDurableExecutionStateResponse> {
    const response = await fetch(`${this.endpoint}/state`, {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify(params),
    });

    if (!response.ok) {
      throw this.toClientError(
        "Failed to read execution state",
        response.status,
      );
    }

    return response.json() as Promise<GetDurableExecutionStateResponse>;
  }

  async checkpoint(
    params: CheckpointDurableExecutionRequest,
  ): Promise<CheckpointDurableExecutionResponse> {
    const response = await fetch(`${this.endpoint}/checkpoint`, {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify(params),
    });

    if (!response.ok) {
      throw this.toClientError("Checkpoint failed", response.status);
    }

    return response.json() as Promise<CheckpointDurableExecutionResponse>;
  }

  // Tell the SDK whether to end just this invocation or the whole execution.
  private toClientError(
    message: string,
    status: number,
  ): DurableExecutionClientError {
    return new DurableExecutionClientError(`${message}: ${status}`, {
      scope:
        status >= 400 && status < 500 && status !== 429
          ? // A rejected request will not succeed on retry.
            DurableExecutionClientErrorScope.EXECUTION
          : // Throttling and server-side errors may.
            DurableExecutionClientErrorScope.INVOCATION,
    });
  }
}

export const handler = withDurableExecution(myHandler, {
  durableExecutionClient: new HttpDurableExecutionClient(
    process.env.DURABLE_ENDPOINT!,
  ),
});
```

没有说明的范围,每一次失败都被当作是短暂的,所以一个永久的被重审 直到处决时间结束 请注意,在SDK自己的范围之前,人们相信有明确的范围 检查错误,所以一个运输 包另一个承担责任 将它所包裹的错误分类.

为了保持Lambda的运输, 但要自己配置客户端, 传递给 `DurableExecutionApiClient` 而不是使用被贬值的 `client` 选项 :

```typescript
import { DurableExecutionApiClient } from "@aws/durable-execution-sdk-js";
import { LambdaClient } from "@aws-sdk/client-lambda";

export const handler = withDurableExecution(myHandler, {
  durableExecutionClient: new DurableExecutionApiClient(
    new LambdaClient({ region: "us-west-2", maxAttempts: 5 }),
  ),
});
```

## 日志

访问已丰富日志 :

```typescript
const handler = async (event: any, context: DurableContext) => {
  context.logger.info("Processing started", { userId: event.userId });

  try {
    const result = await context.step("process", async (ctx) => {
      ctx.logger.debug("Step executing");
      return processData();
    });

    context.logger.info("Processing completed", { result });
    return result;
  } catch (error) {
    context.logger.error("Processing failed", error);
    throw error;
  }
};
```

自定义日志 :

```typescript
context.configureLogger({
  customLogger: {
    log: (level, message, data, error) =>
      console.log(`[${level}] ${message}`, data),
    error: (message, error, data) => console.error(message, error, data),
    warn: (message, data) => console.warn(message, data),
    info: (message, data) => console.info(message, data),
    debug: (message, data) => console.debug(message, data),
  },
  modeAware: false, // Optional: show logs during replay (default: true)
});
```

**本地开发提示 :** 设定 `modeAware: false` 以在重放时查看所有日志,这可以帮助调试:

```typescript
context.configureLogger({ modeAware: false });
```

### AWS Lambda 的动力工具( TypeScript)

`createPowertoolsLogger` 包裹一个 [动力工具 `Logger`](https://docs.powertools.aws.dev/lambda/typescript/latest/features/logger/)。然后每个日志条目都包含持久执行元数据: `executionArn`, (中文(简体) ), `requestId`, (中文(简体) ), `tenantId`, (中文(简体) ), `operationId`, (中文(简体) ), `operationName`,以及 `attempt`。没有值的密钥会被省略。 每个条目还包含配置插件所添加的字段, 如 OTel 插件 `traceId` 财务报告和审定财务报表 `spanId`,如同默认日志的条目.

```typescript
import { Logger } from "@aws-lambda-powertools/logger";
import {
  createPowertoolsLogger,
  DurableContext,
  PowertoolsDurableLogger,
  withDurableExecution,
} from "@aws/durable-execution-sdk-js";

const logger = new Logger({ serviceName: "my-service" });

export const handler = withDurableExecution(
  async (
    event: { orderId: string },
    context: DurableContext<PowertoolsDurableLogger<Logger>>,
  ) => {
    context.configureLogger({ customLogger: createPowertoolsLogger(logger) });
    context.logger.info("workflow-started", { orderId: event.orderId });
  },
);
```

-   声明 `context` 作为 `DurableContext<PowertoolsDurableLogger<Logger>>`,如上. (中文(简体) ). 礛 `context.logger` 而步骤日志接受 Powertools 参数类型。 没有声明, `context.logger` 接受任何参数.
-   密钥使用与默认日志机和Python SDK相同的名称.
-   在日志调用中传递的密钥会用同名的元数据密钥取而代之. 元数据替换密钥为 `appendKeys` 或者说 `persistentKeys`,因为Powertools应用的每个调用键后面这些.
-   适配器读取每通呼叫的元数据. 所以一个适配器实例记录正确 `operationId` 财务报告和审定财务报表 `attempt` (c) 对同时采取的步骤和儿童的背景.
-   仅读出功用工具 `message` 从一个 `Error` 成为第一个争论, 要登录堆栈,通过 `Error` 作为后来的论点: `context.logger.error("charge failed", error)`。 。 。 .
-   SDK并不依赖于 `@aws-lambda-powertools/logger`。安装到您的函数中.
-   `logger.addContext(context.lambdaContext)` 添加 Powertools Lambda 上下文字段, 例如 `cold_start` 财务报告和审定财务报表 `function_name`。还添加 `function_request_id`,重复 `requestId`对于租户范围的处决,它增加了 `tenant_id`,重复 `tenantId`。电源工具在 `Logger` 举个例子 因此,当几个引用同时在一个过程中进行时,例如关于Lambda管理案例,它们具有援引的价值观 `addContext` 最后一个 持久的元数据字段没有这个问题.

离开 `POWERTOOLS_DEV` 已部署的函数中未设置环境变量。 当它被设定时, Powertools通过全球写作 `console`使用 Lambda 的 JSON 日志格式, Lambda 将每个 `console` 在 JSON 对象中行。 因此,每个Powertools 条目在 `message` 第二个 JSON 对象的字段.

这个 `powertools-logger` 用于定义它自己的适配器类的示例, 适配器类会写出 snake case key(`execution_arn`, (中文(简体) ), `request_id`, (中文(简体) ), `operation_id`) (中文(简体) ). `createPowertoolsLogger` 写入骆驼Case键 。 如果您复制了这个示例, 可将日志查询和度量过滤器更新到骆驼 案件名称.

## 运行时间要求

SDK的目标是Lambda管理的节点运行时间(`nodejs22.x`, (中文(简体) ), `nodejs24.x`),在其中 下面的一切都自动满足。 它也运行在一个 **带有您的容器图像 拥有 JavaScript 运行时间**,这就是如何在运行时间Lambda上部署持久函数 无法管理.

在装入时,SDK会导入这些节点所建的: `async_hooks`, (中文(简体) ), `crypto`, (中文(简体) ), `events`, (中文(简体) ), `node:console`, (中文(简体) ), `node:crypto`, (中文(简体) ), `node:fs/promises` (单位:千美元)`mkdir`, (中文(简体) ), `readFile`, (中文(简体) ), `writeFile`, (中文(简体) ), `node:path`, (中文(简体) ), `node:url` 财务报告和审定财务报表 `node:util`说明a **名为 EME 的缺失导出导入 在舱载时致命**,最初不使用——所以运行时间提供模块但不能使用 成员 SDK 的进口将因 `SyntaxError` 在你的操作员运行之前.

也装入 `@aws-sdk/client-lambda` 在第一个检查站,通过动态导入。 如果你捆绑 与 `@aws-sdk` 标记外部,运行时间必须提供该客户端.

### 没有 Async 本地服务器的运行时间

一些轻量级的跑步时间—— [专 员](https://github.com/awslabs/llrt)例如——执行 只有节点 API 的一部分。 SDK探测并围绕两个缺口工作 否则就是 致命 :

-   **`async_hooks.AsyncLocalStorage`** 用于跟踪在全局运行的持久操作 `await` 边框。 没有它,SDK只能回到同步码内追踪.
-   **`util.formatWithOptions`** 用于默认日志。 没有它,SDK会回到 `util.format`。 。 。 .

**检查和重放不受影响**,检查站数据为同字节. SDK每一次执行环境都会发出一个警告 是否为:

|  | 对不运行时间的影响 `AsyncLocalStorage` |
| --- | --- |
| 之后发布的日志记录 `await` | 输 `operationId`, (中文(简体) ), `operationName` 财务报告和审定财务报表 `attempt` |
| 重放- 意识记录 | 无法禁用重放记录, 因此重放边框后的日志语句会被重新发送到 **每次重播** 这增加了长期处决的云表成本 |
| 在内部使用父上下文或兄弟上下文 `runInChildContext` | 仅在同步发生时检测到 |

最后一个项目是防止真正的决定性错误, 所以如果你部署在这样的运行时间, 启用 `no-nested-durable-operations` 规则从 [`@aws/durable-execution-sdk-js-eslint-plugin`](https://www.npmjs.com/package/@aws/durable-execution-sdk-js-eslint-plugin), (中文(简体) ), 它在建设时也发现了同样的错误.

表现是一个与支持不同的问题. 持久处决重放,重放成本增加 以已完成的操作数量计算,所以没有JIT的运行时间总体上可以更慢 具有大型操作的工作流程计数或计算重级步骤——即使开始得更快. 在切换前测量你自己的工作量 .

## 许可证

这个项目根据Apache-2.0许可证获得许可证.

## SDK 3.x 插件迁移

见 [2.x至3.0移徙指南](https://npmcn.com/package/docs/migration-2.x-to-3.0.md) 页:1 软件包版本,实例前/之后,提供者包装,以及验证.

SDK 3.x要求从遗留的v1供应商合同中明确迁移. 供应商声明 `pluginApiVersion` 以 `PluginLoadError` 内 两者 `plugins` 财务报告和审定财务报表 `DURABLE_EXECUTION_PLUGINS` 登记。 他们不是沉默的 调用不同的寿命 : v1 `createPlugin()` 跑一次每个操作员, 而一个3.x工厂 `createPlugin(info)` 每次引用一次.

将遗留的提供者/机构登记改为工厂对象:

```typescript
import { withDurableExecution, type InvocationInfo } from "@aws/durable-execution-sdk-js";

const factory = {
  createPlugin(info: InvocationInfo) {
    return new MyPlugin(info);
  },
};
const handler = withDurableExecution(myHandler, { plugins: [factory] });
```

为每次引用返回一个新插件实例 。 继续有意分享 援引范围之外的资源,如追踪提供者/出口商; 将特定引用的跨度、操作图和缓冲器保留在内。 删除 遗产 `pluginApiVersion` 财务报告和审定财务报表 `pluginType` 迁移工厂后的元数据. 环境加载模块仍在导出 `durableExecutionPluginProvider`,其 值现在是这个工厂形状。 升级捆绑的 OTel 层与核心 3.x 并使用其工厂建造者; 旧的 1.x 层被拒绝而不是 默然再释. Core 2.x 支持的 v1 供应商不受此影响 主要政策.

## 常见问题

### @aws/durable-execution-sdk-js 是什么？

类型脚本的 AWS 持久执行语言 SDK

### 如何安装 @aws/durable-execution-sdk-js？

在项目目录运行 npm install @aws/durable-execution-sdk-js，或使用 pnpm add / yarn add / bun add。

### @aws/durable-execution-sdk-js 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @aws/durable-execution-sdk-js 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @aws/durable-execution-sdk-js 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=22。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @aws/durable-execution-sdk-js 可以商用吗？

@aws/durable-execution-sdk-js 使用 Apache-2\.0 许可。宽松许可：允许商业使用、修改和再分发，并附带明确的专利授权；分发时需保留许可与 NOTICE 文件，修改过的文件要注明改动。以上为概括，不构成法律意见，请以许可原文为准。

### @aws/durable-execution-sdk-js 的下载量有多少？

根据 npm 官方下载统计，@aws/durable-execution-sdk-js 在 2026/10/08 – 2026/11/06 这 30 天内被下载 3,907,208 次，日均约 130,240 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @aws/durable-execution-sdk-js 还在维护吗？

最新版本 3\.0\.0 发布于 2026/10/26（12 天前）；至今共发布 26 个版本，其中过去 12 个月发布了 26 个；首次发布于 2025/11/25。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

