@aws/durable-execution-sdk-js

中文文档
3.0.0发布于 2026/10/26Apache-2.0TypeScriptESM + CJS构建来源已验证近 30 天下载 390.7万

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

中文使用文档
文档目录31 节
  1. 特征
  2. 安装
  3. 快速启动
  4. 文档
  5. 核心概念
  6. 持久语句
  7. 步骤操作
  8. 儿童背景
  9. 引用其他函数
  10. 等待操作
  11. 有条件的等待
  12. 外部调用
  13. 批量操作
  14. 地图
  15. 平行
  16. 提前完成
  17. 承诺组合者
  18. 操作子类型
  19. 配置
  20. 动态仪器插件
  21. 仪器操作状态和出错
  22. 重试策略
  23. 步骤语义
  24. 抖动策略
  25. 自定义运输
  26. 日志
  27. AWS Lambda 的动力工具( TypeScript)
  28. 运行时间要求
  29. 没有 Async 本地服务器的运行时间
  30. 许可证
  31. SDK 3.x 插件迁移

JavaScript 的 AWS 持久执行 SDK

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

特征

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

安装

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

快速启动

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 参考 - 附有详细类型定义和操作规格的完整技术参考
  • 概念和使用案例 - 了解重放模式、最佳做法和现实世界的例子,包括GenAI代理、人入工作流程和saga模式
  • 捐款 - 学习如何为JavaScript的 AWS 持久执行 SDK 做出贡献

核心概念

持久语句

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

步骤操作

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

// 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()。 。 。 .

儿童背景

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

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 函数并等待完成 :

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

等待操作

在指定期限内暂停执行 :

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

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

有条件的等待

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

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) },
      };
    },
  },
);

外部调用

等待外部系统完成操作 :

// 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 } },
);

批量操作

地图

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

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功能.

平行

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

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() 如果失败必须阻止处理者:

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

承诺组合者

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

// 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在检查站中记录了子类型并传递给插件. 因此,执行历史和插件可以过滤这些部件而不解析名称.

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 以这种方式建造的现成作业,例如 microvm。 。 。 .

配置

动态仪器插件

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

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

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

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

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数字 :

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 以确定该尝试是否失败。 一个外部 没有错误细节的调回失败仍然拒绝调回承诺 保留其失败的运行状态; 可选的仪器细节没有 改变呼叫者的结果 或坚持状态.

重试策略

自定义重试策略 :

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

步骤语义

控制执行保证:

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

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

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

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

抖动策略

防止雷鸣群:

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 类型 :

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 选项 :

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 }),
  ),
});

日志

访问已丰富日志 :

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;
  }
};

自定义日志 :

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 以在重放时查看所有日志,这可以帮助调试:

context.configureLogger({ modeAware: false });

AWS Lambda 的动力工具( TypeScript)

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

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 本地服务器的运行时间

一些轻量级的跑步时间—— 专 员例如——执行 只有节点 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, (中文(简体) ), 它在建设时也发现了同样的错误.

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

许可证

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

SDK 3.x 插件迁移

见 2.x至3.0移徙指南 页:1 软件包版本,实例前/之后,提供者包装,以及验证.

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

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

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 共发布 26 个版本,首次发布于 2025/11/25;过去 12 个月发布了 26 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
3.0.0latest2026/10/2612 天前
2.7.12026/10/2018 天前
2.7.02026/10/1722 天前
2.6.02026/10/021 个月前
2.5.02026/09/301 个月前
2.4.02026/09/091 个月前

关于 @aws/durable-execution-sdk-js 的常见问题

@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 和提交记录判断。