# @durability/transforms 中文文档

规范地址：https://npmcn.com/package/%40durability/transforms/

版本：0\.6\.1
npm 元数据更新时间：2026-11-10T12:52:43.723Z
中文译文更新时间：2026-11-13T00:37:41.120Z
软件包许可：ISC

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

原始 npm 页面：https://www.npmjs.com/package/%40durability/transforms
原文对照：https://npmcn.com/package/%40durability/transforms/?lang=original
项目主页：https://github.com/avenceslau/durability/tree/main/packages/transforms#readme
源码仓库：https://github.com/avenceslau/durability

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

- 包体积（解压后）：122 kB，39 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：3 个
- peer 依赖：vite ^8\.0\.0，wrangler 4\.107\.0，better-result ^2\.9\.2，@cloudflare/workers-types ^4\.20260702\.1
- 首次发布：2026-07-14T03:18:25.652Z
- 最新版本发布：2026-11-10T12:52:42.418Z
- 近 30 天下载量：12448（2026-10-13 至 2026-11-11，npm 官方下载统计）
- 已发布版本数：7（近 12 个月 7 个）

## 中文简介

Cloudflare RPC 的已打入调取器和调取器

## 安装

```sh
npm install @durability/transforms
```

也可以使用：`pnpm add @durability/transforms`、`yarn add @durability/transforms`、`bun add @durability/transforms`

## README

# @ 耐用/ 变形

Cloudflare 持久对象和工人服务装订 RPC 的打入式呼叫器和呼叫器转换.

## 安装

```sh
npm install @durability/transforms
```

## 虚拟设置

Vite 插件需要 Wrangler , 读取其已验证的绑定配置, 包装可持久对象的根和所有其他对象绑定( 服务, KV, R2, Workflows, 队列等) , 生成添加声明 `.with(...)` 他们的怒火型。 瓦斯,秘密, 和模块blobs没有被触及。 诸如交叉工人服务等无法推断的Wrangler类型的捆绑物在运行时被包裹,但保留其手写声明.

```ts
const value = await env.CACHE.with(timeout, 1_000).get('key');
await env.MEDIA.with(retry, 2).put('file.txt', body);
const instance = await env.JOBS.with(timeout, 5_000).create({ params });
```

呼叫器只在客户端上运行 。 被调用者的变换和调用语境仍然需要您拥有的持久对象或工人 Entry 点 .

不进行变换,被包裹的捆绑行为与原作完全相同,包括同步方法和RPC承诺活线. 变换后,每一次呼叫都返回一个承诺 仍然支持管道连接,例如 `stub.with(timeout, 1_000).counter().increment()`;连锁呼叫等待被改变的结果,而不是分享其来回. 关于返回物体的方法,例如: `WorkflowInstance`,没有改变.

对于 `DurabilityRouting.client({...})` 财务报告和审定财务报表 `DurabilitySemaphore.client({...})`,插件注入 `exportName` 从目标持久对象的同模块导出。 目标必须是该模块输出的本地类,并被宣布为Wrangler本地持久对象类(包括迁移类). 支持导出别名 :

```ts
import { DurableObject } from 'cloudflare:workers';
import { DurabilityRouting as Routing } from 'durability/routing';

class InternalMailbox extends DurableObject {
  enqueue(input: string) {}
}
export { InternalMailbox as Mailbox };

const router = Routing.client({
  target: InternalMailbox,
  invoke: (stub, input) => stub.enqueue(input),
  ...defaults,
});
```

结果 `exportName` 附加在其它属性后,所以扩展不能覆盖它。 查取故意限于在同一工人模块中可见的类申报和出口;进口类,再出口,动态目标,以及非入行配置在目标可见时被单独或拒绝. 设定 `exportName` 很明显是那些案子的逃生口 明确 `exportName` 值永远不会改变.

```ts
import { defineConfig } from 'vite';
import { doTransforms } from '@durability/transforms/vite';

export default defineConfig({
  plugins: [doTransforms({ wrangler: './wrangler.jsonc' })],
});
```

生成的宣告默认为 `do-transforms.generated.d.ts` 在万克勒旁边 `main` 模块。 在应用程序的 TypeScript 项目中包含该文件 .

### 恢复已断裂的持久对象根

许多持久对象出错留下了根断裂,因此每次通过它发出的呼叫都会以相同的出错而失败. 启用 `restoreBrokenStubs` 重写插件的命名空间 `get` 财务报告和审定财务报表 `getByName` 调用后, 产生的分接点将替换为:

```ts
doTransforms({ wrangler: './wrangler.jsonc', restoreBrokenStubs: true });
```

失败的呼唤仍然拒绝,并且没有被重审. 下一个调用从命名空间获得一个与原参数相同的新分位符,这些参数只被评估一次,所以 `env.MY_DO.get(env.MY_DO.newUniqueId())` 继续位于同一对象。 替换发生在呼叫器变换链的末端,所以每次尝试都是由 `retry` 运行在新鲜的树枝上。 没有插件, 使用 `createRestorableStubFactory(env.MY_DO, 'getByName')(name)`。 。 。 .

## 定义并安装变换器

```ts
import { DurableObject } from 'cloudflare:workers';
import {
  applyTransforms,
  createTransformContextTarget,
  defineTransform,
  registerTransform,
} from '@durability/transforms';

type RequestContext = { requestId?: string };

class ExampleObject extends DurableObject {
  setContext(context: RequestContext) {
    return createTransformContextTarget(this, context);
  }

  async greet(name: string) {
    return `Hello, ${name}`;
  }
}

const observability = defineTransform<ExampleObject, RequestContext>()
  .caller(
    (requestId: string) =>
      async ({ next }) =>
        next({ context: { requestId } })
  )
  .callee((metricName: string) => async ({ context, next }) => {
    console.log(metricName, context.requestId);
    return next();
  });

applyTransforms(ExampleObject, {
  methods: {
    greet: [registerTransform(observability, 'greet_calls')],
  },
});

const stub = env.EXAMPLE.getByName('example').with(
  observability,
  crypto.randomUUID()
);

await stub.greet('Ada');
```

`applyTransforms` 变异类原型并被累积. 在模块初始化时调用一次, 而不是每个请求或实例 .

为持久对象类定义的调用器变换也收到 `actorId`,则 `DurableObjectId` 中标的物体。 为其他目标定义的变换,例如: `defineTransform<object>()`,不看到字段,而永久对象转换不能附加在不是永久对象根的绑定上。 身份证留在呼叫者身上,不发给被呼叫者:

```ts
const actorLog = defineTransform<ExampleObject>().caller(
  () =>
    async ({ actorId, method, next }) => {
      console.log('rpc', method, actorId.toString());
      return next();
    }
);

await env.EXAMPLE.getByName('example').with(actorLog).greet('Ada');
```

变换上下文是不信任的调用元数据. 它适合申请身份证、追查和暗示,但不能被接受为身份、租赁、角色或授权的证据。 由独立认证的被调用人数据衍生授权.

## 内置呼叫器变换

```ts
import { retry, timeout } from '@durability/transforms';

const value = await stub
  .with(timeout, 5_000)
  .with(retry, {
    retries: 3,
    delay: ({ attempt }) => Math.min(1_000 * 2 ** (attempt - 1), 30_000),
  })
  .read();
```

呼叫者暂停等待, 但不会取消远程操作 。 每一次重试都是新的RPC引用,因此重试只使用"一能"方法或通过"一能"键. 何时 `delay` 被省略,重试时使用被盖住的指数后退并全焦.

其他内置设施包括:

-   `betterResultCodec` 用于序列化和再水合 `better-result` 在一个版本信封中的值。 遗留的0.1.0有效载荷因形状模糊而默认被否决;临时设定 `acceptLegacy: true` 只有在与一个年长的被调用者沟通时.
-   `errorBoundary` 将调用器可见的抛出转换为“更好的结果”出错.
-   `abortAsSuccess` 将预期持久对象重置为未定义的成功结果.
-   `largeObjectStream` 以传输大型 JSON 对象结果。 它需要一个标准Schema验证器,并强制使用一个调用器解码限制,但它仍然缓冲了完整的序列化表示;使用本土流进行无约束的数据.

## 手工包装

当 Vite 插件无法使用时, 直接包入目标或命名空间 :

```ts
import {
  createTransformStub,
  timeout,
  withTransforms,
} from '@durability/transforms';

const service = createTransformStub(env.MY_SERVICE).with(timeout, 5_000);
const namespace = withTransforms(env.MY_DURABLE_OBJECT);
const id = namespace.idFromName('example');
const object = namespace.get(id).with(timeout, 5_000);
```

## 常见问题

### @durability/transforms 是什么？

Cloudflare RPC 的已打入调取器和调取器

### 如何安装 @durability/transforms？

在项目目录运行 npm install @durability/transforms，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：better-result（^2\.9\.2）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @durability/transforms 支持 TypeScript 吗？

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

### @durability/transforms 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @durability/transforms 可以商用吗？

@durability/transforms 使用 ISC 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @durability/transforms 的下载量有多少？

根据 npm 官方下载统计，@durability/transforms 在 2026/10/13 – 2026/11/11 这 30 天内被下载 12,448 次，日均约 415 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @durability/transforms 还在维护吗？

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

