# @drupflare/cartridge 中文文档

规范地址：https://npmcn.com/package/%40drupflare/cartridge/

版本：0\.3\.1
npm 元数据更新时间：2026-09-30T17:43:36.456Z
中文译文更新时间：2026-11-13T05:23:32.013Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40drupflare/cartridge
原文对照：https://npmcn.com/package/%40drupflare/cartridge/?lang=original
项目主页：https://github.com/drupflare/cartridge
源码仓库：https://github.com/drupflare/cartridge

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

- 包体积（解压后）：179 kB，17 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：2 个
- 首次发布：2026-08-14T05:20:11.604Z
- 最新版本发布：2026-09-30T17:43:36.057Z
- 近 30 天下载量：2201（2026-10-13 至 2026-11-11，npm 官方下载统计）
- 已发布版本数：7（近 12 个月 7 个）

## 中文简介

在 Cloudflare 持久对象中运行一个被屏蔽的被解释器

## 安装

```sh
npm install @drupflare/cartridge
```

也可以使用：`pnpm add @drupflare/cartridge`、`yarn add @drupflare/cartridge`、`bun add @drupflare/cartridge`

## README

# 弹匣

> 在 Cloudflare 持久对象中运行一个被屏蔽的被解释器

[![Build](https://github.com/drupflare/cartridge/actions/workflows/build.yml/badge.svg)](https://github.com/drupflare/cartridge/actions/workflows/build.yml) [![Interpreters](https://github.com/drupflare/cartridge/actions/workflows/e2e.yml/badge.svg)](https://github.com/drupflare/cartridge/actions/workflows/e2e.yml) [![Prettier](https://github.com/drupflare/cartridge/actions/workflows/prettier.yml/badge.svg)](https://github.com/drupflare/cartridge/actions/workflows/prettier.yml) [![codecov](https://codecov.io/gh/drupflare/cartridge/branch/master/graph/badge.svg)](https://codecov.io/gh/drupflare/cartridge) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://npmcn.com/package/%40drupflare/cartridge/LICENSE)

墨盒在一个 Cloudflare 持久对象内运行一个被屏蔽的被子解释器 。 过 `createCartridge()` 一个主题模块和呼叫 `run()`;再入门;中断口罩 文件系统为您设置了线程 。 每件物品都会被出口给需要的呼叫者.

工人运行时间是同步的,而原声翻译不是同步的。 两项重叠的援引 共享一个可变的机器—— globals, 打开文件描述符, 会话状态 —— 和 interleave into 似乎错误的输出而不是失败.

这里没有关于 PHP 的具体信息 。 实际建筑贯穿 `tests/interpreters/` 每推一推: **第8.3页** (日语), **卢亚 5.4** (是月亮), **氯乙烯 3** (P), **快速JS** (速记), **克鲁比3.4** (Ruby.wasm, over WASI 而不是标注)和 **爪哇语** (字节框,提前编译而未解读). 见 [推进 用户.md](https://npmcn.com/package/%40drupflare/cartridge/ADVANCED_USAGE.md) 每个语言状态和每种语言的食谱.

* * *

## 目录

-   [为什么是卡特里奇](https://npmcn.com/package/%40drupflare/cartridge/#readme--why-cartridge)
-   [安装](https://npmcn.com/package/%40drupflare/cartridge/#readme--install)
-   [快速启动](https://npmcn.com/package/%40drupflare/cartridge/#readme--quick-start)
-   [这里是什么](https://npmcn.com/package/%40drupflare/cartridge/#readme--what-is-here)
-   [子路径导出](https://npmcn.com/package/%40drupflare/cartridge/#readme--subpath-exports)
-   [Ergonomics (环形画)](https://npmcn.com/package/%40drupflare/cartridge/#readme--ergonomics)
-   [处理错误](https://npmcn.com/package/%40drupflare/cartridge/#readme--error-handling)
-   [复出门](https://npmcn.com/package/%40drupflare/cartridge/#readme--reentrancy-gate)
-   [中断遮罩](https://npmcn.com/package/%40drupflare/cartridge/#readme--interrupt-mask)
-   [文件系统](https://npmcn.com/package/%40drupflare/cartridge/#readme--filesystem)
-   [主管](https://npmcn.com/package/%40drupflare/cartridge/#readme--supervisor)
-   [尾矿工人](https://npmcn.com/package/%40drupflare/cartridge/#readme--tail-worker)
-   [两层](https://npmcn.com/package/%40drupflare/cartridge/#readme--two-layers)
-   [测试](https://npmcn.com/package/%40drupflare/cartridge/#readme--testing)
-   [相关仓库](https://npmcn.com/package/%40drupflare/cartridge/#readme--related-repositories)
-   [许可证](https://npmcn.com/package/%40drupflare/cartridge/#readme--license)

* * *

## 为什么是卡特里奇

一个被翻译者是 **单可变机**。环球,自动装入器缓存,容器 指针,打开文件描述符和会话状态都是全过程的. 两起重叠的援引 不要大声地失败。 它们相互交织,产生可信的错误输出.

Cloudflare的运行时间是相反的形状. 它是事件驱动的, 它将幸福地提供第二 请求时,第一个已停放。 持久物体缩小范围,但不要关闭.

所以,主机必须提供 四个东西 口译员不能为自己提供: 串行化,一种方式 在主机呼叫中挡住一个中断, 这个文件系统在启动时不会花一大笔钱, 和一条不会在它修理的东西里面运行的修理道.

每一个都默不作声。 无假名的回叫表象 `SuspendError` 从哪里 opcode计数器在数月后着陆 负载不足.

* * *

## QQ 安装

```sh
bun add @drupflare/cartridge
```

两个运行时间依赖关系, `fflate` 财务报告和审定财务报表 `fzstd`两个同步减压器 一个懒惰的山 在同步内充气 `open()` 预压缩的翻译器充气 范围; 两点都不能等待 `DecompressionStream`,它也仅限于gzip和放出.

* * *

## QQ 快速启动

```ts
import { createCartridge } from '@drupflare/cartridge';

const cartridge = createCartridge({
  // whatever your build's factory is; forward the io it gives you
  instantiate: (io) => initInterpreter({ print: io.print, printErr: io.printErr }),
  // files every run should see, written once at boot
  files: { 'lib/helper.txt': 'shared by every run' }
});

const result = await cartridge.run('print("hello")');
console.log(result.stdoutText); // "hello\n"
console.log(result.status); // 0
```

这是默认路径。 每个条目都是连续的,每个 `print` 装入口罩,脚本是 在文件系统之前 `callMain` 输入,并用名称报告被泄露的口罩深度 毒死下一个跑道.

**你的建筑必须满足** 是两个成员:

```ts
interface Interpreter {
  FS: MountFS; // emscripten's FS: mkdir, writeFile, and optionally utime
  // may answer a promise, for an adapter with work to finish after main returns
  callMain(argv: string[]): number | void | Promise<number | void>;
}
```

这是标语为 `main()`\- 程序与 `-sINVOKE_RUN=0` 财务报告和审定财务报表 `-sEXPORTED_RUNTIME_METHODS=callMain,FS`。 。 。 . **大多数出版的建筑不这样做**曾经是月亮 活地, 快速标记、红宝石、花字节和字节都检查过了,6个出口中没有一个 `callMain`,因此将其写作"双行适配器"是正常的例而非倒置. `createMemoryFS()` 当一个建筑也没有文件系统时,则提供另一半,以及 `FS` 是三种方法签名 而不是标注对象, 所以一个WASI预开也满足它。 见食谱在 [推进 用户.md](https://npmcn.com/package/%40drupflare/cartridge/ADVANCED_USAGE.md),每个标签 实际运行.

* * *

## 这里是什么

| 模块 | 它会做什么 |
| --- | --- |
| `lazy-fs.ts` | MEMFS 从每个文件包的分层上挂上第一个打开的文件 |
| `supervisor.ts` | 断路器 修理梯子 |
| `cartridge.ts` | `createCartridge()`:高级默认值,以及 `RunResult` |
| `mount.ts` | 急切地奔流而行,驾车而行, `mountRecord()`, (中文(简体) ), `createMemoryFS()` |
| `tail-worker.ts` | {\\fn黑体\\fs22\\bord1\\shad0\\3aHBE\\4aH00\\fscx67\\fscy66\\2cHFFFFFF\\3cH808080}把一个尾巴工人的事件 归纳成一个人类读到的东西 {\\fn黑体\\fs22\\bord1\\shad0\\3aHBE\\4aH00\\fscx67\\fscy66\\2cHFFFFFF\\3cH808080}我从小到大 |
| `mask.ts` | 重算中断口罩,加上 VM 切片计数器 |
| `inflate.ts` | 同步 zstd: 内容大小, `inflateZstd`,一个被支持的解码器 |
| `util.ts` | `fromUtf8`编号 :`toUtf8`, (中文(简体) ), `encodeJson`编号 :`decodeJson`, (中文(简体) ), `toBytes`, (中文(简体) ), `splitLines` |
| `serialize.ts` | `Gate`: 1名口译员, 一次引用 |
| `errors.ts` | 五个名称出错词汇表,每个都有一个稳定的点 `code` |
| `worker-shim.ts` | 使标注 `ENVIRONMENT=worker` 在工人身上建造即时电源d |

* * *

## 子路径导出

一个包裹, `sideEffects` 诚实地宣布, 和一个子路径 每一个顾虑 你没有使用.

| 导入 | 里面有什么东西 |
| --- | --- |
| `@drupflare/cartridge` | 下方除了烟雾 |
| `@drupflare/cartridge/cartridge` | `createCartridge()`, (中文(简体) ), `RunResult`, (中文(简体) ), `Interpreter` |
| `@drupflare/cartridge/gate` | `Gate`, (中文(简体) ), `doGate`, (中文(简体) ), `GateStats` |
| `@drupflare/cartridge/mask` | `createMask`单子, `vmFromBinary`切片计数器 |
| `@drupflare/cartridge/fs` | 两座山, `mountRecord`, (中文(简体) ), `createMemoryFS`,两个包索引形状 |
| `@drupflare/cartridge/inflate` | 同步zstd,用于一个在后靴上充气的预压缩模块 |
| `@drupflare/cartridge/supervisor` | 铁丝网, `CircuitBreaker`,分类账 DDL |
| `@drupflare/cartridge/tail` | 佣人和纯洁的仆人 |
| `@drupflare/cartridge/util` | 字节、字符串和 JSON 便利 |
| `@drupflare/cartridge/errors` | 错误词汇表 |
| `@drupflare/cartridge/shim` | **副作用**; 在粘结值评估前导入以生效 |

> \[尖叫声\] `sideEffects` 是数组而不是 `false`。 。 。 . `worker-shim.ts` 补丁 `globalThis` 在导入时间; 声明包无副作用将允许捆绑树摇 删掉 `Asyncify` 断接并恢复 **无法捕获** 请求杀死。 声明 `true` 将禁用摇动整个软件包。 该阵列是唯一诚实的答案,和 `tests/exports.spec.ts` 钉住它.

* * *

## Ergonomics (Ergonomics) (英语)

**永远不要建立 `TextEncoder` 用于使用此软件包.** 每个有效载荷 `string | Uint8Array`· ; 将字节交回的任何东西 也都交回解码文本.

```ts
import { createCartridge, fromUtf8, toUtf8 } from '@drupflare/cartridge';

const cartridge = createCartridge({ instantiate });

// a string or bytes, both fine
await cartridge.run('print(1)');
await cartridge.run(fromUtf8('print(1)'));

// structured input, no encoder at the call site
await cartridge.writeJson('input.json', { items: [1, 2, 3] });

const result = await cartridge.run('read input.json and print a total');
result.stdout; // Uint8Array, the primitive
result.stdoutText; // string, what you wanted
result.json<{ total: number }>(); // parsed
result.lines(); // ['{"total":6}']
result.lastLine(); // the last line, no trailing empty element
result.assertOk(); // throws InterpreterError naming the status and stderr
```

生道犹在

```ts
// the module itself, instantiated if needed, handed over inside the gate
const raw = await cartridge.interpreter();

// or run arbitrary work against it, still serialised against every other entry
await cartridge.withInterpreter((module) => module.FS.writeFile('/tmp/x', 'by hand'));
```

命名是固定的,所以可以学习一次: `to*`编号 :`from*` 用于编解码器(`toUtf8`, (中文(简体) ), `fromUtf8`, (中文(简体) ), `*Json` 页:1 序列/区间(`writeJson`, (中文(简体) ), `encodeJson`, (中文(简体) ), `decodeJson`, (中文(简体) ), `*Text` 用于解码字段(`stdoutText`, (中文(简体) ), `.json()` 编号 : `.lines()` 最终结果.

* * *

## QQ 错误处理

五个名字,一个基地,每个都带一个稳定的点 `code`匹配代码,而不是 信件文本.

| 类 | 默认代码 | 升起时 |
| --- | --- | --- |
| `CartridgeError` | `cartridge.error` | 底; 以及 JSON 编码拒绝 |
| `GateError` | `gate.error` | 闸门被滥用,或者看到两跑一次 |
| `MaskViolationError` | `mask.violation` | 面罩不均匀,或蒙面时试图悬浮 |
| `MountError` | `mount.error` | 一个包是无法到达的, 或者FS拒绝写 |
| `BudgetError` | `budget.exceeded` | 切片、居民字节上限或中断津贴 |
| `InterpreterError` | `interpreter.error` | 即时,无入站,无出站,有口罩 |

```ts
import { InterpreterError, isCartridgeError } from '@drupflare/cartridge';

try {
  (await cartridge.run(script)).assertOk();
} catch (error) {
  if (error instanceof InterpreterError && error.code === 'interpreter.nonzero_exit') {
    // the script failed, which is different from the interpreter failing
  } else if (isCartridgeError(error)) {
    // something in the cartridge layer; error.code says which seam
  }
}
```

代码使用与 `supervisor.ts`是因为 `Finding.code`,所以一个抛出的错误和一个 有记录的关于同一缺陷的发现与没有翻译表相关.

* * *

## \* 留校口

`Gate` 串行输入解释器:一次引用一次,排入FIFO顺序.

今天每个主机的呼叫都是同步的,所以还没有重叠. 一个暂停电话——JSPI, a 正在等待的查询, 一个出局的取回—— 足够第二个请求输入, 而第一个请求是 停车要求中.

有两个不同的机制:

| 机制 | 工作地点 | 为何不只这个 |
| --- | --- | --- |
| `Gate` | 一个纯洁的劳动者,一个坚忍的、, `wrangler dev` | 便携式,什么测试驱动 |
| `ctx.blockConcurrencyWhile()` | 仅限持久对象 | 更强的,运行时间停止了 事件,但它的上限为 30 s ,不能被巢 |

`doGate(gate, ctx)` 是组合,和顺序事项: 门已输入 **第一个** 编辑 挡板被取入其中 绝不相反; `blockConcurrencyWhile` 无法筑巢. 传出 a `ctx` 改为 `createCartridge()` 你自动得到它.

> \[叹息\] **在电话里找到门 已经挂起它就永远挂起**,没有错误. `alarm()` 整个封口时 `fetch()` 因此,在添加有门的入站点之前,请检查是否 你已经在其中之一.

* * *

## · 断开口罩

`mask.ts` 是最没有明显存在理由的作品. `_zend_wasm_slice_arm(period)` 火灾 越战中断 **密码计数器,不是接缝**和JSPI不能中止 堆与JS 里面的画框.. `SuspendError: trying to suspend JS frames`. 多个主机的电话正好设置了这个框架 翻译堆栈下方: SQL桥, 里面的解码器, 记录器, 每种能力 呼叫,每个懒惰的FS `inflateSync`和每个 `print` 调用.

因此中断时间必须在主机通话期间被扣住并随后被放出. 面具 实值 **重新计算**由于这些呼叫巢穴, 它暴露了柜台 所以泄漏是可见的而不是 推断:

```ts
import { createMask } from '@drupflare/cartridge/mask';

const mask = createMask();

const rows = mask.withMask(() => {
  // any host call that puts a JS frame under the interpreter goes here
  return [];
});

const { enters, nested, maxDepth, deferred, violations } = mask.stats();
```

4个属性,每个属性都是一种无声错误的方式:

1.  **被贬.** 案例之巢——主机呼叫可以触发懒惰的FS读取——和不计数 内出入口的口罩解密.
2.  **旗子上挂着一面旗子.** `zend_wasm_tick_fired()` 跳过 `EG(vm_interrupt)` 除非宿主记得,否则边界就会消失.
3.  **预算在解职后重新检查**不仅在民意测验现场 一个充气成员为~1毫秒 本地比例,所以一个被遮住的窗口可以自行超过一片.
4.  **肯定的断言** 暂停从不发生在深度0以上. `MaskViolationError` 被丢弃 而不是吞没.

`createCartridge()` 给每个弹匣一个 **新鲜** 口罩而不是模块单子: 二 一个隔离的口译是两个C边的计数器,共用一个主计数器将使两者都成为 深度错误。 单通为工人使用的单通解释案保留出口.

> \[注\] 主机轨道的深度是 **东道主** 深处。 C处理器在使用期间自我伪装 自己的回报,所以 `zend_wasm_slice_stat(4)` 在收益范围内读取1,这是正确的,而不是 违反。 永远不要断言这一点.

* * *

## QQ 文件系统

3个挂载,用于3个不同大小的问题.

| 函数 | 对于 | 费用 |
| --- | --- | --- |
| `mountRecord()` | 手持的几个文件 | 无;平地 `Record<string, string | bytes>` |
| `mountDrupalStreaming()` | 一整棵树,在靴子上铸造 | 一分一分,一分一分 |
| `mountDrupalLazy()` | 一整棵树, 每个文件在第一个上充气 `open()` | 1个居民压缩blob+1个LRU |

`mountRecord()` 是一个第一需要的 `createCartridge({ files })` 给你打电话 A 类 包是 11 421 文件 CMS 树的正确答案 和 3 文件的错误答案 an 翻译需要运行一个脚本.

当建筑有了 **没有自己的文件系统** - 速成图不出口,并出口一台TeaVM或 WASI目标没有标记 `FS` 或者是.. `createMemoryFS()` 是一个 `MountFS` 一个以上 `Map`,与 `read()` 财务报告和审定财务报表 `readText()` 所以适配器从不构建 `TextDecoder`。 。 。 . `MountFS.utime` 可选 出于同样的原因:是月亮的Lua建造了一艘真正的船标 `FS` 没有 `utime` 完全没有,而且只有 `mountDrupalStreaming()` 从不叫它.

懒惰的山体开始冷却 温度为3,754毫秒 `cpuTime` 财务报告和审定财务报表 **3,066毫秒是那座山**。图层按顺序合并,所以驱动程序或补丁可以阴影一个 未重建的基底包,以及 `InflateStats` 报告实际夸大的内容——哪些 是衡量懒惰是否付出的尺度.

> \[大 **`StreamPackEntry` 财务报告和审定财务报表 `PerFilePackEntry` 不属于一类,不得合并.** `o` 表示 不同的东西:流线索引被相抵入了 INFLated 连接 `core.bin.gz` 生产、每个文件的指数相抵为压缩blob和需要 `c` 旁边 `l`一个 覆盖两者的界面将提供 `o` 两个意义和制造 `c` 可选 `materialise()`, (中文(简体) ), 计算 `blob.subarray(e.o, e.o + e.c)` 并且会得到 `NaN`。 。 。 .

还有两项行为:

-   **图层在节点创建前合并**,所以后面的一层会覆盖同一路径上较早的一层.
-   **平面还原取决于打开的文件描述器表,在相同的fd数字上.** 窗口对齐 已经 **没有** 物质:测量和伪造的(将每个inode转换为1个和500个两种) 恢复同字节。 丢弃 `/dev/urandom`单 fd 扔出; 丢出 sqlite 的 fd 给定 锁定- 校正错误 **80-120 二档**,在边缘运行时间是一个吊 请求,而不是错误。 如果你触摸了挂载或快照路径,那就是无常.

R2支持层成本 **零子请求**,使R2成为可变层的正确商店.

* * *

## 主管

`supervisor.ts` 持有必须是 JavaScript 的健康层的一半 : **修补路径不能 取决于它修复的子系统.**

译者不能看到JS 被扔出一个垃圾堆, `@` (单位:千美元) `catch` 既无用,又整个援引无效——不能观察它自己的孤立被杀死 无法相信自己一旦被下毒后会修复自己。 所以这些班级的检测和修理 都活下来了 在这里.

**每条绊倒线都相当于一个缺陷 这个项目已经运出,然后找到.** 这是 选择标准, 并每个人命名它的事件。 没人见过火的支票就是装饰.

断开器会衰减而不是循环: 窗口内相同的代码 N 次会提升一个运行 梯子,一个干净的间隔会衰变一跑, 并用一个命名的理由限制尝试.

```ts
import {
  CircuitBreaker,
  quarantineDecision,
  runHostTripwires
} from '@drupflare/cartridge/supervisor';

const findings = runHostTripwires({ status: 200, bytes: 0, path: '/' });
const { quarantine, reason } = quarantineDecision(findings);
// quarantine === true, reason === 'render.empty: 200 with 0 bytes'
```

**检疫击败了错误的输出.** 一个503 `Retry-After` 答案比0字节200还好 这个工程运出了0字节200——然后缓存了它,然后从边缘服务.

* * *

## 尾矿工人

`wrangler tail` 仅在操作员被附加时报告 CPU。 尾巴工人也一样 追踪平台内部的事件,持续且没有操作员在场.

也带有 **金丝雀**。CPU分配结果 整个切片设计依赖于 无证行为:工作停放在一个持久对象引用中,工作恢复在另一个对象引用中 收取的费用 **恢复** 引证. 如果Cloudflare改变这一点,产品中没有任何失败 大声地——让自己不再适应。 这么说吧 `evaluateCanary()` 重新检查变量,阈值为 **比率** 而不是毫秒。 绝对 `cpuTime` 以colo为单位的不同(一种 一次部署的46毫秒是另一次部署的75毫秒).

* * *

## 🏗 二层

姊妹图书馆 `edgeport` 使用双层规则: `src/core/` 唯一的代码 导入平台原始,每个公共模块都以此为基础. 这个规则不会转移 在这里.

**弹匣没有从平台上进口任何东西.** `grep -rn "from 'cloudflare" src/` 返回无. 其原始内容是: `Module` 带有 `FS` - 被立即攻击 **消费者** 交给我 `instantiate`,而持久对象状态作为可选对象到达 `BlockingContext` 上面有一个方法。 所以两层的分裂是用来保护的 已满足于没有要包含的平台导入 .

转让和应用什么:一个包的子路径输出,诚实的 `sideEffects` 声明,一个统一的出错词汇表,带有逃生舱门的ergonomics,以及配方,每个配方由 一个绿色的光谱.

* * *

## 测试

```sh
bun run typecheck
bun run test # in workerd
bun run test:coverage
bun run test:interpreters # 40 assertions against real wasm builds, in node
```

**382通过,99%的发言.** 门在下方 `@cloudflare/vitest-pool-workers`,所以这个 内部执行 **工人d** 而不是节点,和覆盖使用 `provider: 'istanbul'` 而不是说 `v8`。这是一个运行时间事实,而不是偏好:v8提供者从节点读取覆盖 检查员,这些测试 运行在工人的隔离, 所以它属性0 而每次测试 通过.

四个括号,每个括号都诚实地说明可以证明什么:

| 括号 | 何处 | 证明 |
| --- | --- | --- |
| 行为过假 | 多数规格 | 合同,没有 40 MB 二进制 |
| 真实的平台原始 | `mount.spec.ts` (真正的gzip,真实) `Response`, (中文(简体) ), `Fetcher`(中文(简体) ) | 向上并写入路径到结束 |
| 来文方的断言 | `lazy-fs.spec.ts`,该部分 `mask.spec.ts` | 没有假的可以进入 |
| 一个真正的原子弹翻译器 | `tests/interpreters/` (PHP,Lua,CPython,快活JS,Ruby,Java) | 一个真正的建筑满足 `{ FS, callMain }` |

最后一道是唯一能让 `ADVANCED_USAGE.md` 说 **已验证**它的建筑是 被钉住 `devDependencies` 故能修饰之以相接 `e2e.yml` 每推一推,都有警卫 如果进行零测试或跳过任何测试, 则失败 : 一个默默跳过的道读取为通道 .

* * *

## 有关仓库

| 仓库 | 这是什么 |
| --- | --- |
| [`drupflare/worker`](https://github.com/drupflare/worker) | 消费者:Cloudflare工人上的Drupal 11 |
| [`drupflare/durabledb`](https://github.com/drupflare/durabledb) | 进口 `/gate` 财务报告和审定财务报表 `/mask` 用于其SQL桥 |
| [`drupflare/phasm`](https://github.com/drupflare/phasm) | 构建解释器,包括 VM 中断补丁口罩驱动器 |
| [`drupflare/stream-http`](https://github.com/drupflare/stream-http) | ưμ㼯A `https://` 流包, 在一个被注入的抓取上 |
| [`drupflare/untarl`](https://github.com/drupflare/untarl) | 取出无节点API的焦油和焦油.gz |

* * *

## 许可证

MIT (c) 格雷戈里·米切尔 2026. 见 [自由主义](https://npmcn.com/package/%40drupflare/cartridge/LICENSE)。 。 。 .

## 常见问题

### @drupflare/cartridge 是什么？

在 Cloudflare 持久对象中运行一个被屏蔽的被解释器

### 如何安装 @drupflare/cartridge？

在项目目录运行 npm install @drupflare/cartridge，或使用 pnpm add / yarn add / bun add。

### @drupflare/cartridge 支持 TypeScript 吗？

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

### @drupflare/cartridge 支持 ESM 还是 CommonJS？

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

### @drupflare/cartridge 可以商用吗？

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

### @drupflare/cartridge 的下载量有多少？

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

### @drupflare/cartridge 还在维护吗？

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

