# @dee-wan/cache 中文文档

规范地址：https://npmcn.com/package/%40dee-wan/cache/

版本：2\.2\.0
npm 元数据更新时间：2026-11-04T10:52:27.476Z
中文译文更新时间：2026-11-14T12:28:02.539Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40dee-wan/cache
原文对照：https://npmcn.com/package/%40dee-wan/cache/?lang=original
项目主页：https://github.com/dee-wan-cms/cache#readme
源码仓库：https://github.com/dee-wan-cms/cache

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

- 包体积（解压后）：776 kB，66 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=20
- 运行依赖：1 个
- peer 依赖：@prisma/client \>=6\.19\.3 \<7
- 首次发布：2026-09-20T18:24:00.186Z
- 最新版本发布：2026-11-04T10:52:27.118Z
- 近 30 天下载量：2049（2026-10-12 至 2026-11-10，npm 官方下载统计）
- 已发布版本数：12（近 12 个月 12 个）

## 中文简介

Prisma 读取 Cloudflare 工人和 D1 的缓存, 由持久对象协调

## 安装

```sh
npm install @dee-wan/cache
```

也可以使用：`pnpm add @dee-wan/cache`、`yarn add @dee-wan/cache`、`bun add @dee-wan/cache`

## README

# @dee-wan/ cache (英语)

Prisma 读取 Cloudflare 工人和 D1 的缓存 。 永久对象坐标无效, 填充锁 和缓存值。 默认值为检查协调员 。 可选区域条文允许有限度地僵化.

合同,包括每项无效规则和限制,均在 [文件/合同](https://npmcn.com/package/%40dee-wan/cache/docs/cache-contract.md)。 。 。 .

## 生成配置

```prisma
generator cache {
  provider = "dee-wan-cache-generator"
  output   = "../src/generated/cache"
  exclude  = ["AuditLog"]   // optional
}

/// @cache.skip
model Session {
  id String @id
}
```

运行 `npx prisma generate` (或运行 npm 脚本) `prisma generate`写作 `cache-config.ts`。 。 。 . 提供者名称解决通过 `node_modules/.bin`因此,Prisma二进制必须运行 npm `PATH`。 。 。 . 每个模型都可以缓存,除非它携带 `/// @cache.skip` 或列于 `exclude`读取 包括不缓存的选定退出模式。 更新此软件包后再生成: 扩展 拒绝其它格式的配置.

## 把它接入一个工人

```ts
import { PrismaD1 } from "@prisma/adapter-d1";
import { createCacheExtension } from "@dee-wan/cache";
import { createDurableObjectStore } from "@dee-wan/cache/cloudflare";
import { cacheConfig } from "./generated/cache/cache-config";
import { Prisma, PrismaClient } from "./generated/prisma";

export { CacheCoordinator } from "@dee-wan/cache/cloudflare";

export default {
  async fetch(request, env, ctx) {
    const prisma = new PrismaClient({ adapter: new PrismaD1(env.DB) }).$extends(
      createCacheExtension({
        config: cacheConfig,
        decimal: Prisma.Decimal,
        enabled: env.CACHE_ENABLED !== "false",
        generation: env.CACHE_GENERATION,
        scope: "public",
        store: createDurableObjectStore(env.CACHE_COORDINATOR, { name: "main-db" }),
        waitUntil: (promise) => ctx.waitUntil(promise),
      }),
    );
    // ...
  },
} satisfies ExportedHandler<Env>;
```

```jsonc
{
  "durable_objects": { "bindings": [{ "name": "CACHE_COORDINATOR", "class_name": "CacheCoordinator" }] },
  "migrations": [{ "tag": "cache-v1", "new_sqlite_classes": ["CacheCoordinator"] }]
}
```

Prisma运行的查询扩展按应用顺序排在最外端(在Prisma 6.19.3上核实). 在缓存前应用 prisma- guard 等按调用扩展 :

```ts
const client = base.$extends(guardFor(caller)).$extends(createCacheExtension({ ...options, scope }));
```

然后每读一读,包括点击率和重写论点(例如租户) filter)是缓存密钥的一部分. 在命中跳过缓存后应用的扩展名 。 使用 `scope` 任何调用者都会改变结果而不改变论据.

## 区域Prisma读取

`createRegionalStore` 将本地 Cloudflare Cache API 读取到同一协调商店 。 选择到 最多有5秒的数据被隔离 授权和警卫延期仍在运行.

```ts
import { createDurableObjectStore, createRegionalStore } from '@dee-wan/cache/cloudflare';

const name = 'main-db';
const generation = `${deploymentGeneration}:${cacheConfig.cacheVersion}`;
const store = createRegionalStore(createDurableObjectStore(env.CACHE_COORDINATOR, { name }), {
  namespace: env.CACHE_COORDINATOR.idFromName(name).toString(),
  generation,
  ttlMs: 5000,
  waitUntil: promise => ctx.waitUntil(promise),
});
const extension = createCacheExtension({
  config: cacheConfig,
  store,
  coordinationGeneration: generation,
  scope: callerScope,
  decimal: Prisma.Decimal,
  waitUntil: promise => ctx.waitUntil(promise),
});
```

保持命名空间稳定 跨来电者和作家。 它确定一个协调员和数据库,而不是 用户。 保持呼叫权限 `scope`。 。 。 . `coordinationGeneration` 必须匹配包装的一代. 接受和协调员的点击加上已知的新最后期限可以输入区域条目。 他们 寿命从不超过源新鲜度的最后期限。 仍未完成的旧/海关商店 工作,但他们的点击率没有覆盖区域条目。 刷新符号从不重复区域播放 . 与 `waitUntil`后半期区域租约的点击率 背景情况。 续作每把按键被分解并保持相同的新鲜度. 读取/释放 等待被限制; 超时后释放后锁. 续约失败允许再次尝试 而不延迟前景命中;已过期的条目仍然使用协调器. 本地突变阻断了旧的读取和填充. 按顺序共享写符的操作; 排队操作保持栅栏,直到实际的协调员呼叫得到解决,包括在呼叫后 暂停 。 跨同位素变化在区域租约内趋同. 区域读取屏蔽。 与 `waitUntil`,后面读取在有限制的背景通行证中重试协调员。 只恢复缓存 在承认后, 永远不要仅仅因为时间流逝。 追踪失败溢出或再利用 未解决的写入失败令牌使隔离禁用 . 缓存 API 失败使用协调器; 协调员读取失败使用原始数据库路径.

生成的后端使用此包装并 `createResponseWarmup` 从同一个入口。 他们暖和 以当前呼叫者的资质,通过正常的授权,设定了边界生成的GET路由. 发热是最好的努力;未知的查询变体和先行请求可以保持冷. 写作和认证 裁决不缓存。 取暖读取的目标并不是所有网络请求的暂时性保证.

## 选项

无效的选项扔出 a `TypeError` 在建筑.

| 选项 | 默认 | 含义 |
| --- | --- | --- |
| `config` | —— 说 | 生成相克. |
| `store` | —— 说 | `createDurableObjectStore(namespace, { name, attempts?, locationHint? })`。 。 。 . |
| `decimal` | 无 | `Prisma.Decimal`当方案有十进制字段时需要. |
| `enabled` | `true` | `false`:读写跳过协调员. `$cacheInvalidate` 仍然叫着它. |
| `scope` | `""` | 每把钥匙的一部分. |
| `generation` | 无 | 1.256 chars, 与协调员有联系的每个工人都一样。 更改它会使每个条目都失效一次 . |
| `excludeModels` | `[]` | 在生成的配置上运行时间选择退出 . |
| `shape` | 新鲜3600 s,负600 s,软比0.8 | `{ default, byModel }`. TTL必须最多为28,747,636 s. |
| `waitUntil` | 无 | 启用软 TTL 后刷新 . |
| `leaseMs` | 60 000 个 | 写作租赁,最多60万. |
| `lockMs` | 3万块 | 最多30万个. |
| `fillPollDelaysMs` | 20,40,80,160,320,640 (英语) | 等待时另一个请求会填充相同的密钥 。 持卡人持锁时间超过整个预算后,读者停止等待. |
| `maxValueBytes` | 150000 (150000) (韩语) | 提供了更大的结果,但没有缓存。 最多为1900. |
| `onError` | 无 | 接收协调器, 序列化和写出错误 . |

`createDurableObjectStore(namespace, { name, attempts, locationHint })`数字 :

-   `name` (需要)识别D1数据库. 密钥不包括数据库, 所以有两个数据库 共享一个协调员名称将共享缓存行 。 每个数据库使用一个名字.
-   `attempts` (默认 3, 最多为 10) 是针对可重试协调器错误的尝试总数 开始,结束和无效.
-   `locationHint` (单位:千美元)`wnam`, (中文(简体) ), `enam`, (中文(简体) ), `sam`, (中文(简体) ), `weur`, (中文(简体) ), `eeur`, (中文(简体) ), `apac`, (中文(简体) ), `oc`, (中文(简体) ), `afr`, (中文(简体) ), `me`将 第一创作协调员,尽最大努力.

## 原始 SQL 写入

Raw SQL 不通过扩展. 包起来:

```ts
await prisma.$cacheRawWrite({ models: ["Post"] }, () => env.DB.prepare("UPDATE Post SET ...").run());
await prisma.$cacheInvalidate({ entities: [{ model: "Post", pk: [42] }] });
await prisma.$cacheInvalidate({ all: true });
```

通过外国密钥提及目标的模式也被作废. 未知的模型名称丢出 .

## 规划行为

-   读取器无法到达:读取到D1,没有被缓存.
-   无法接触或在写作前超载的协调员: `CacheUnavailableError` 被抛出并写下 不运行。 缓存读取和写取共享一个协调器,因此重读负载可以拒绝写取.
-   写作时 `enabled: false` 没有跟踪。 变动 `generation` 当缓存转回时 打开或呼叫 `$cacheInvalidate({ all: true })`。从不一起运行禁用版本和启用版本.
-   一个新的计划或软件包版本会使第一次接触时的每个条目无效. 不同工人 绑定在一个协调员身上的版本,在其中一个版本保留之前,一直相互无效.
-   回滚到发布会 与一个年长的协调员 存储计划 使得每写失败 `CacheUnavailableError`前进.
-   批次内读取 `$transaction([...])` 未缓存。 Prisma 的 D1 适配器拒绝交互 交易.
-   通过D1读取 `withSession` 不支持复制件 .
-   一个协调员的持久目标有1 000个每秒请求的软限制。 测量 2026-09-17 来自一个客户端:约1,030个缓存每秒读取21ms p50,没有出错,对: 约340每秒215米直接读取D1. 高比率没有计量.
-   每名协调员打一通电话、一通失事、二通失事、七通费用; 每个书写需要2个,加上复写。 关于"工人自由计划", 要求让许多普里斯玛打电话 可以达到子请求限制(参见合同"Cost per Prisma call").
-   每个给模型的书写都会使模型的缓存列表,计数和关系读取无效.
-   缓存条目上限为每名协调员1GiB;最接近到期的条目被先被拆出.
-   每个被缓存的读物都会到一个协调员地点进行往返。 从亚洲测量 2026-09-17:击出8-14分 协调员在 `apac` 和171至210毫秒,装入 `weur`慢点 而不是直接读取附近的D1(48–103 ms). 将协奏器放置在大部分流量附近 `locationHint`;远离它的用户读取速度比没有缓存要慢.

## 运行时间要求

-   Cloudflare 工人有一个 SQLite 支持的持久对象和 D1. 核心条目和Cloudflare条目不需要 `nodejs_compat`; 工人导入 `@dee-wan/cache/d1` 这需要它.
-   Prisma 6.19.3 或较新的 6.x 与 `@prisma/adapter-d1` (以6.19.3测试).
-   发电机:节点20或更新(CI运行于20,22和24日). Wrangler 4和Miniflare需要22号节点.

## 发展

```sh
npm run build
npm run lint
npm run typecheck        # builds, generates the test client, then checks src and tests
npm run test:unit        # Node 22.5+ (node:sqlite)
npm run test:workerd
npm run test:consumer    # packs, installs into a fresh Worker project, runs it on workerd
```

所部署的烟雾(仅在可支配账户上使用;测试工人对持有的呼叫者任意使用SQL) 符号 :

```sh
npm run test:prepare
npx wrangler d1 create <name>                       # put the id into a copy of test/deployed/wrangler.example.jsonc
npx wrangler d1 execute <name> --remote --file test/workerd/.build/schema.sql
npx wrangler deploy -c <copy> --var SMOKE_TOKEN:<random>
CACHE_SMOKE_URL=https://<worker> CACHE_SMOKE_TOKEN=<random> npm run test:deployed
npx wrangler delete --name <worker> && npx wrangler d1 delete <name>
```

`test/workerd/.build/schema.sql` 作者为 `npm run test:workerd`。 。 。 .

## D1 有防守的Prisma 写出栅栏

`@dee-wan/cache/d1` 出口 `cacheD1Env`, (中文(简体) ), `wrapD1Handler`, (中文(简体) ), `createD1CacheRuntime`, (中文(简体) ), `d1PrismaCacheExtension`,以及 `fenceD1Writes`消费者提供 `D1CacheProfile` 带有环境前缀,D1绑定名称和前缀,协调对象名前缀, 普里斯马 `readModels`,并明确证明 `unfencedWriteTables`编辑器 通行证直接通过和栅栏 原始D1写,包括批发,执行,和 届会。 未知或模棱两可的文字使用全球围栏。 仅在 它的图案证明它的写作不能通过触发或级联来改变被缓存的数据.

环绕每一个可以触摸到协调器的获取、 预定处理器和单独的写入器 D1数据库. 应用 `d1PrismaCacheExtension` 只有在获得客户授权后,才给予客户 扩展范围。 当缓存或缓存读取时, 运行时间返回不扩展 开始 独立控制和认证客户端应当保持畅通无阻. `@dee-wan/cache/d1/config` 验证工人绑定、数据库身份地图和配对 编剧,并提供通用编剧配置编辑. 消费者必须提供真正的D1 UUIDs,从不绑定对象身份.

`coordinationGeneration` 让 Prisma 扩展共享字面协调器生成 升级时使用生-D1写出栅栏. 如果省略,则从现有规划/配置中得出 协调员的产生保持不变。 Prisma 缓存密钥中总是包含规划器和 生成配置版本。 不将各代协调者混为一谈 推出后,必须让每个作者在允许缓存读取之前参与。 外部 D1 写入 不被截取: 酌情禁用已缓存的读取和写作, 然后使用新鲜的 重现前的刻画.

该套装的Prisma对等支持仍为Prisma 6.19.3和后6.x. D1 写入适配器 独立于 Prisma; 其他 Prisma 版本尚未被此软件包验证 .

### 明确授权如下:

`d1CacheEpoch(database)` 返回一个不透明的数据库身份命名空间, 生成和全球写作时代。 在读取该数据库之前抓取该数据库并包含 每个依赖者都会在外部缓存密钥中捕获命名空间. 错过了时间, 禁用读取, 等待写入或协调器失败返回 `null`; 绕出外部 缓存读取并填入此选项 。 旧的飞行中填充物保留了旧的取名空间. 这不授权请求或取消下游浏览器缓存.

`cacheD1Read(database, { key, scope, dependencies, ttlMs, cacheable }, load)` 缓存 a 明确选择在呼叫者完成授权后阅读。 包含全文 演员、网站、当前权限和所有查询输入 `scope` 财务报告和审定财务报表 `key`列表中 装入器在 `dependencies`。帮助者检查每个独特的 装订全球栅栏在检查前,包括它的一代和关键时代,以及 再检查一次,然后给一个击中或存储一个填充。 未知运行时间的待写, 较旧的协调员、 检查失败或禁用读取会绕过缓存 。 默认 TTL 30秒,最多5分钟。 值和密钥为边框; 不支持 对象绕行缓存。 日期、大字节和字节数组使用现有的值编码器.

`cacheD1JsonRead(database, { key, scope, dependencies, ttlMs, request, buffered: true }, load)` 被调用者知道JSON是缓冲器, 它会保持 错失时的原始响应,并保留了命中时的响应头. 条件、范围、, 预览和能力请求、错误答复、饼干、下载、不安全 `Vary`, (中文(简体) ), 编码后的尸体和体型过大的尸体绕行了缓冲. 无 `buffered: true`,回应 绕行;从不为流设置. 反应缓冲是字节并有时间限制的. 这些帮助者使用私人持久对象存储,而不是公共缓存 API.

对于本地 Prisma 读取, 也取决于另一个 D1 数据库, 使用 `withD1PrismaCache(client, database, config, { scope, dependencies })` 打电话后 警卫 范围必须包括完整的行为者、网站和许可背景。 业务 键包括依赖时间并重新检查点击率的依赖性。 最初的三论 形式保留其现有行为。 所有参与的作家必须用同样的栅栏 物理数据库协调员.

D1协调员的电话每次有2秒钟的截止日期。 失败时读取回 D1 ; 写入需要成功的开始 。 失败的结束保存数据库结果并保存 租赁保守派 晚起后和读取锁在和解后被清理.

`keyArgs` 可选地将参数读取为缓存键身份。 保留这个身份中所有改变结果的输入. 执行和无效使用原始参数. 回调错误绕过缓存 .

### 区域读取缓存

`cacheD1Read` 范围 `d1PrismaCacheExtension` 编号 : `withD1PrismaCache` 接受 `regionalTtlMs` 从0到5000。 默认为0(严格协调). 一个正值选择在本地 Cloudflare Cache API 中产生有边框的 Stale ; 其它作者的更改可能不会在最长的间隔内被忽略 。 严格读取使用 0 。 Cache API 失败回到了严格的路径. 此选项缓存值, 而不是 HTTP 响应 .

关键内容包括数据库和协调员身份、世代、范围和查询身份. `regionalModels` 可选择限制 Prisma 区域读取其根和所有相关模型被列出的查询。 呼叫者必须提供一个范围,将影响结果的每一个授权背景分开. `keyArgs` 必须保留每个改变结果的论点。 习惯 `createD1CacheRuntime` 提供稳定、独特的 `regionalIdentity` 每名协调员;没有一位协调员,则绕过区域层.

`cacheRegionalResponse(request, { namespace, ttlMs, waitUntil? }, load)` 是一个选择进入的区域缓存 匿名公众Get JSON 响应。 使用稳定的部署/版本命名空间和不超过5000毫秒的TTL. 证书、预览、有条件和缓存通道请求到达 `load`仅明确公开作出正面反应 `s-maxage` 资格。 浏览器的响应需要重新验证;内部过期自启动起仍受限制 `load`。缓存 API 错误返回到 `load`。呼叫者必须将此仅适用于公共线路,并且必须在请求或命名空间中包括所有响应-不同请求输入.

`wrapD1ReadResponseLease(handler, profile)` 从 `@dee-wan/cache/d1/response-lease` 可选择的再利用认证得到回复。 设定 `readResponseLease.maxSeconds` 从1起至300起(违约5起),并明确设定 `<PREFIX>_READ_ACCESS_SECONDS` 从 1 到该最大值( 默认 0) 。 把它包进去 `wrapD1Handler`. JSON 响应机构在填充时被验证,最多可有8,000,000活字节;在不解码和保存客户端头的情况下点击缓存机构流. 普通区域读取值仍以1 500 000字节为上限。 配置文件提供数据库绑定,部署环境变量,被认可路径,证书和变化头,以及新鲜-cookie名. A 类 `*` 路径段匹配一个非空段。 密钥包括完整请求的 URL, 配置的证书和不同的标题, 配置, 释放, 以及配置的 D1 身份 。 可选 `cookieNames` 为密钥选择对大小写敏感的 cookie 名称, 同时保留每次发生及其顺序; 它需要 `cookie` 内 `credentialHeaders` 在生成模式中, 列表中的新鲜度饼干。 包含用于认证或响应变异的每个饼干. 没有它,就会使用完整的 Cookie 头条. `bypassQueryParams` 可选地列出绕过租赁的精确查询密钥. `ignoreRequestCacheControl` 浏览器发送时可选择允许租赁点击 `no-cache` 或者说 `no-store`; 默认为假. 设定 `refreshAheadSeconds` 到整数从 0 到 0 `maxSeconds` (缺省0)在背景中刷新有效租赁,即将到期 `waitUntil` 已提供。 当窗口超过活动租赁期限时,刷新前端被禁用 。 命中值保持即时状态,每把密钥在隔离区重新聚集。 成功的新鲜、经授权的反应将产生新的有限度的租约;失败的刷新使旧的到期不变。 一个配置 `freshnessHeader` 强制读取源。 符合条件的成功反应取代了普通租约;不安全反应不能取代租约。 过期仍受新的源请求和授权/数据最后期限的限制。 配置每个证书和响应变化头 。 工人需要 `nodejs_compat`。 。 。 .

成功认证后, 拨打 `limitD1ReadLeaseUntil` 与证书的绝对过期 以时间为毫秒。 缺少、未确定或已过期的最后期限,无法填补。 来源收到 `Cache-Control: no-cache` 租借失败。 成功的突变设置了 HttpOnly 新鲜的饼干,用于配置的最大值 。 默认 `bypass` 模式,请求携带它绕过租赁。 可选 `freshnessCookieMode: 'generation'` 需求 `cookie` 内 `credentialHeaders`:每个突变产生新的饼干值,其第一次读取时使用新数据后,反应才能被再用. 遗留或无效的标记仍然绕行. 一个再利用的区域查询值在该值的原始到期时上限响应租赁;一个新的源负载不会被查询-cache TTL所上限. `freshnessCookieExcludedPaths` 可选地将已知的非移动路径从此 cookie 中排除,使用相同的整块路径匹配。 在有效的租赁中, 匹配 `If-None-Match` 或者说 `If-Modified-Since` 返回无体 304; `If-None-Match` 以优先为准。 其他先决条件和范围到达处理者。 除了无体的304以外,客户反应头没有改变。 写总是执行处理器。 其他行为者的授权变更可延续到租赁期,对缓存的读物生效.

响应-租赁和区域 D1 缓存检查最多等待100 ms;超时使用误差. 前景寒冷读取最多100 ms等待相同的密钥,然后可以替换被停滞的主人. 前场失事可以立即替换出一个背景温暖的主人. 开始的旧缓存在替换填充前完成 .

内部温暖的读取和背景刷新了一次绑定的JSON,然后重放这些字节用于缓存填充和发现. 前景反应持续流出.

当认证运行在一个单独的可信服务绑定中时, 将服务处理器包入 `wrapD1ReadLeaseOrigin(handler)` 和使用情况 `forwardD1ReadLease(request, service)` 在网关租赁处理器内。 原产地包提供了请求- 本地截止范围 。 转发方只将已核实的最后期限转移至装订后,在回复前取出其内部头条. 一个网关必须信任绑定的服务来验证证书并保护这个内部证据.

浏览器客户端可以导入 `createReadFreshness(policy)` 从 `@dee-wan/cache/client` 使用相同的 `readResponseLease` 政策。 打电话 `observe(scope, method, url, transport?)` 成功响应后,然后合并 `headers(scope, method)` 输入请求。 使用生成模式,通过请求源、基址和 `withCredentials: true` 将饼干用于确认的同源写作;其他运输工具则保持新发头倒置。 数据突变可以使每个范围配置的最大值有新的 GET 头; 排除路径使用与服务器相同的整块规则 .

对于没有D1协调的应用程序,导入 `wrapReadResponseLease` 财务报告和审定财务报表 `limitReadResponseLeaseUntil` 从 `@dee-wan/cache/response-lease`。通过处理器和一个包含稳定非空的选项对象 `namespace`, (中文(简体) ), `deployment`,以及 `database` 身份, 活动 `seconds` 价值,以及上述相同的响应-租赁政策领域(不包括 `databaseBinding` 财务报告和审定财务报表 `deploymentEnv`) (中文(简体) ). 认证后, 拨打 `limitReadResponseLeaseUntil` 与实际的证书过期时的相差相差数以毫秒; 没有未来的最后期限, 无法存储回复。 当部署或基础数据源发生变化时,身份必须改变。 本条目使用缓存 API 存储,不需要 D1 运行时间或持久对象 。 这需要工人 `nodejs_compat` (c) 请求-当地截止日期范围。 可选 `wrapReadResponseLeaseOrigin` 财务报告和审定财务报表 `forwardReadLease` 支持与 D1 适配器相同的可信服务约束截止日期运输.

独立反应租赁接受可选 `warmup` 政策。 与一个 `waitUntil` 上下文中,它从背景开始,在符合条件的缓存命中或成功的 JSON 源响应以及未来的授权期限后读取。 第一位冷小姐仍然到达源头. 在任何需要的瞄准镜后,用 `scope: null` 先运行,然后学习目标, 在普通种子之前。 配置 `scopeHeader` 内 `varyHeaders`; 如果缺少温度, 则取消温度。 例如,将这些字段添加到独立的租赁选项中:

```ts
{
  varyHeaders: ['x-scope-id'],
  warmup: {
    scopeHeader: 'x-scope-id',
    seeds: ['/api/context', '/api/items'],
    discoverScopeFrom: '/api/context',
    discover: (url, body) => {
      if (url.pathname === '/api/context' && body && typeof body === 'object' && 'scope' in body && typeof body.scope === 'string') {
        return { scope: body.scope, targets: ['/api/items/recent'] };
      }
      return { targets: [] };
    },
    portable: (url) => url.pathname === '/api/items/recent',
  },
}
```

`seeds` 和发现的目标必须是租赁路径和查询政策所承认来源相同的URL. 一个终端 `**` 路径段匹配后人; `*` 仍然匹配一个非空段。 导入 `matchesReadResponsePath` 从 `@dee-wan/cache/response-lease` 在调用者政策中应用相同的路径。 发现可能在原始请求没有范围标题时提供范围. 设定 `discoverScopeFrom` (c) 其余目标等待其授权的响应和有效范围。 如果发现范围失败,则批量停止。 当范围已经知道时,范围种子作为普通的去迭代种子运行. 运行时要考虑目标预算 此选项需要 `discover` 和条目 `seeds`只标记一个 URL `portable` 当它的路径和查询没有包含任何秘密,并且在该范围内可以安全分享时;默认是虚假的。 区域目录只存储可移植的URL,大致数和时间,而不是证书或反应机构. 缓存的回复仍按现有演员资格和不同标题键。 区域缓存 API 更新是相近的, 可能会有比赛 .

用于每件有信誉的多范围变暖 `catalogScope: 'credential'`。边框目录按键为已配置的证书和不同标题,但 `scopeHeader`,加上租赁身份。 它按其合并的URL计数排序范围,再按计数排序URL. 使用 `{ url, scope }` 内 `seeds` 或发现目标,将瞄准标头设为1; `scope: null` 将取去. 字符串目标使用当前范围. 任选第三项 `discover` 参数包含触发请求 `scope` (或用靴子解决的范围) `popularScopes` 从证书目录。 设定 `discoveryPriority: 'next'` 以排队的冷种子为前期目标, 被发现的目标保持了发现顺序;在能力上可以替换排队的冷种子,而不是更早的发现. 他们仍然有同样的预算目标。 每个反应仍然使用普通的证书和范围租赁钥匙和授权。 瞄准镜头不得同时是证书头. 仅 `portable` URL输入目录. 目录认证身份省略了新鲜度饼干,所以所学的受欢迎能活下来;反应键和批组保留了那块饼干.

D1,通过 `{ warmup }` 作为可选的第三个参数 `wrapD1ReadResponseLease`; 保持可序列化的配置文件 .

默认为每批48个目标,所有热量批次的4个同时请求以一个包装,25秒的最后期限包括档等,每个范围32个目录条目,24小时TTL. 默认的30秒冷却从批量截止日期后开始. 已完成的批次保留了它的冷却;未完成的被废弃的批次释放出自己的冷却,以便下一个合格的前地读取可以再试取. 在冷却期间,符合条件的前台访问仍然更新了受欢迎程度,但不会再开始另一批. 以 `maxTargets`, (中文(简体) ), `concurrency`, (中文(简体) ), `maxMilliseconds`, (中文(简体) ), `maxEntries`, (中文(简体) ), `catalogTtlMs`,以及 `cooldownMs`. 已排队的暖源呼叫向主动前地Get处理器屈服. 温暖使用来电者的资质和普通租赁授权. 温暖读取不会引发更多批次或受欢迎的更新. 可选纯度 `isCurrent()` 当包装器配置退出时调回错误; 排队和运行工作检查并停止, 后批不开始 。 外部写成功 `freshnessCookieExcludedPaths` 取消排队工作,并阻止更老的前地读取在目前隔离范围内填充租约或开始一批;新鲜度世代保留后续反应租约。 被排除的存在,草稿和预览操作使温暖分批运行. 缓存或取暖失败不会改变前景反应.

`createMutationInvalidation(policy)` 从 `@dee-wan/cache/client` 信号在听众和浏览器标签之间成功写入。 打电话 `publish(scope, method, url)` 成功后和 `subscribe(scope, listener)` 待收款项 `{ scope, method, pathname }`; 调用返回的函数以取消订阅 `dispose()` 当完成。 URL的查询和证书没有发送. 使用无证书范围 。 阅读方法和 `freshnessCookieExcludedPaths` 被忽略。 该频道仅在工厂在浏览器中运行时才打开.

`createRevalidationWindow(intervalMs, now?)` 每个瞄准镜自动检查. `remaining(scope)` (一) 规定一个期限,但以后不提出; `take(scope)` 允许在最后期限之前或之后立即有未初始化的范围并初始化的范围。 变异通知仍然立即发出,不使用这个窗口.

`createSingleFlight<Key, Value>()` 同时分享 `run(key, load)` 打电话 已完成和失败的电话被删除; `forget(key)` 允许在旧电话仍在运行时使用新电话.

`createIntentWarmup(cooldownMs?, now?)` 温暖读取导航意图,而不存储响应值。 打电话 `setScope(siteAndActor)` 使用前和 `warm(key, async isCurrent => ...)` 在鼠标徘徊或键盘焦点上。 一项任务正在进行;只有最新的等待意图。 检查 `isCurrent()` 在顺序读取之间。 成功的任务默认冷却60秒. 范围变化和 `invalidate()` 清晰的等待任务和冷却;旧的完成不能温暖新的范围。 使用与普通读取相同的 URL, 证书和信头的无声, 有边框, 只读请求 。 不将结果输入活动编辑器存储或启动启动扇形.

`cacheReadValue` 从 `@dee-wan/cache/scoped-read` 提供缓存 API 值缓存,而不包含 D1 或持久对象。 递出一个非空的 `namespace`,结构化 `key`,则a `validate` 带有源装入器的类型守护。 在密钥中包含每个授权和结果差异范围; 不将证书放入缓存值 . `ttlMs` 默认为 5000; 除非 `maxTtlMs` 明确提高限额(最高可达30万). `maxBytes` 默认为1,500,000,并且可以降低。 可选 `cache` 财务报告和审定财务报表 `now` 允许提供缓存 API 执行和时钟。 缓存失败、 无效值和过期的条目返回加载器; 加载器错误被传播 。 满载器运行前即为过期. 可选 `refresh: { aheadMs, waitUntil, load }` 在背景中刷新符合条件的命中,而不扩展现有条目;成功的重载从开始就收到一个新的TTL.

刷新加载器:读取新源;关闭已丢弃的响应机构. 保存失败或无效刷新 旧的过期。 同时更新每个密钥和缓存的去dupe 。 前景错失使老一点失效 刷新; 已启动的刷新在更新前完成 .

### D1 书签客户端运输

可以设置有界点的 UI `advanceOn: 'mutations-and-fresh-reads'`, (中文(简体) ), `freshnessHeader` 和可选 `excludedPaths`普通人不会推进 存储的地板。 成功的突变方法反应 和明确的新鲜得到做. 非GET/HEAD/OPTIONS方法保守地计算,包括只读的POST. 被排除的平时道路不会推进它. 每一个请求仍然发送存储和 电话供应楼层。 保持乐观调节和审校检查. 放弃这个选项,保留每个响应中的进步.

`createD1BookmarkFetch(fetch)` 将抓取执行包裹并记住有效 `X-Dee-Wan-D1-Bookmarks` 响应头。 以后的请求最多 每个物理数据库都看到书签。 每个独立创建一包 客户端上下文。 书签地图以64个数据库UUID和8192为界 字符; 无效的地图被忽略 。 过 `{ storage }` 作为继续使用原生地图的第二个论据 `getItem`编号 :`setItem` 存储诸如会话Storage。 存储出错倒回内存.

### D1届会议

云花板工人进口 `@dee-wan/cache/d1` 要求 `nodejs_compat` 兼容旗,包括D1会话未启用时.

环绕 HTTP 处理器 `wrapD1ReadSessionHandler(handler, options)` 外部 `wrapD1Handler`设置 `bindingNames`, (中文(简体) ), `bindingPrefixes`, (中文(简体) ), `databaseIdsEnv`,以及 可选择 `primaryBindings`, (中文(简体) ), `freshnessHeader`,以及 `ignoreRequestCacheControl`。命名的环境变量包含一个 JSON 从每个已配置的绑定名称到其物理 D1 UUID 的映射。 约束 共享 UUID 共享请求会话。 如果变量不存在, 绑定会保留 他们的原始行为。 无效的地图失败配置; 无效的书签 信头返回 HTTP 400.

对于可再使用的 Prisma D1 适配器,通过 `prismaD1SessionDatabase(database)` 改为 `PrismaD1` 并运行每个 Prisma 操作通过 `runD1SessionOperation(database, operation)`,包括计划业务. 在同一物理数据库中,录用最多等待30秒,以进行更早的操作。 应用 `sessionD1Env(env, options)` 在缓存包装预定绑定之前 这些手术都使用同样的外观。 普通D1呼叫使用常规 装订。 允许和曝光 `X-Dee-Wan-D1-Bookmarks` 在 CORS 配置中,浏览器客户端需要它. D1缓存源填补从主端开始;缓存点击再利用源书签. 常规 Prisma 缓存必须设置 `sessionCache: d1SessionCacheHooks(database)`。在发送流式响应信头后启动的查询无法推进这些信头。 WebSocket 升级绕行会话.

## 常见问题

### @dee-wan/cache 是什么？

Prisma 读取 Cloudflare 工人和 D1 的缓存, 由持久对象协调

### 如何安装 @dee-wan/cache？

在项目目录运行 npm install @dee-wan/cache，或使用 pnpm add / yarn add / bun add。它还提供命令行工具 dee-wan-cache-generator，可以用 npx dee-wan-cache-generator 直接运行。

### @dee-wan/cache 支持 TypeScript 吗？

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

### @dee-wan/cache 支持 ESM 还是 CommonJS？

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

### @dee-wan/cache 需要什么版本的 Node\.js？

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

### @dee-wan/cache 可以商用吗？

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

### @dee-wan/cache 的下载量有多少？

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

### @dee-wan/cache 还在维护吗？

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

