@domainkit/capsuledb

中文文档
0.23.0发布于 2026/11/03MITTypeScriptES Module构建来源已验证近 30 天下载 2500

在 PostgreSQL 上作为一个声明式 CapsuleDB 胶囊的域Kit 存储

中文使用文档
文档目录6 节
  1. 安装
  2. 把它接起来
  3. 或释放出SQL,并在靴子上坚持
  4. 或者在部署时准备
  5. 表格
  6. 它的保证

@domainkit/capsuledb

域库 Storage 在 PostgreSQL 作为声明 顶点DB 胶囊。 安装到下面 DomainKit.layer 和整个持久性生命周期——提供者 授权、连接、附件、交互式流程续作、计划/核准/接收 尝试,多领域批次,以及观察到的准备状态——生命在你的数据库中,范围扩大到你 租户.

联合国 域名- kit.dev

主机拥有 SqlClient 和它的寿命。 这个软件包拥有自己的桌子,从不暴露 行,查询,或生客户端.

安装

需要卡普尔DB >=0.6.0 <0.7.0 和效果 >=4.1.2 <5.0.0。 。 。 .

bun add @domainkit/capsuledb capsuledb @effect/sql-pg

把它接起来

import { Config, Layer } from "effect";
import { PgClient } from "@effect/sql-pg";
import { Cloudflare, Custody, DomainKit, Vercel } from "domainkit";
import { PgStorage } from "@domainkit/capsuledb";

export const DomainKitLive = DomainKit.layer({
  providers: [
    Cloudflare.provider({
      oauth: {
        clientId: Config.String("CF_CLIENT_ID"),
        clientSecret: Config.Redacted("CF_CLIENT_SECRET"),
      },
    }),
    Vercel.provider(),
  ],
}).pipe(
  // `provideMerge`, not `provide`: `domainkit/server`'s handlers read attempts and receipts
  // straight from Storage, so the layer they are given has to still carry it.
  Layer.provideMerge(Layer.mergeAll(PgStorage.layer(), Custody.layerConfig())),
  Layer.provide(PgClient.layerConfig({ url: Config.Redacted("DATABASE_URL") })),
);

PgStorage.layer() 在启动时准备:它创建了 CapsuleDB 的分类账,应用待迁移,以及 仅提供 Storage。胶囊服务永远无法观测到一个其表格为 失踪.

Custody.layerConfig() 读取 DOMAINKIT_CUSTODY_KEY 在它面前封存每个供货商的证书 到达一行。 换成KMS Custody.layerFromAsync; 没有简单文字模式, 而此 软件包从不看到.

或释放出SQL,并在靴子上坚持

如果你的移民是你们的, 取SQL代替:

capsuledb emit \
  --module ./node_modules/@domainkit/capsuledb/dist/index.mjs \
  --export capsule \
  --dialect postgres \
  --out ./drizzle

上面写着CapsuleDB的分类账DDL, 胶囊的迁移, 和准备行,加上一个 capsuledb.emit.json 索引命名它拥有的文件。 用你自己的管道应用,然后启动 以断言模式 :

PgStorage.layer({ mode: "assert" });

除非数据库已经与胶囊相匹配, 否则将不应用任何模式并失败, 所以丢失 迁移是一个启动失败,而不是一个运行时间的惊喜. capsuledb check 比较已排放 以 CI 中的当前胶囊创建文件夹.

或者在部署时准备

无服务器主机在其部署和靴子中编写数据库而未触及到计划. PgStorage.manifest() 使胶囊的表率相等 PgStorage.layer() 安装,所以 使用堆栈 capsuledb/alchemy 编制函数所主张的内容:

import { PgStorage } from "@domainkit/capsuledb";
import * as CapsuleDB from "capsuledb/alchemy";

const manifest = yield * PgStorage.manifest();
const registry =
  yield *
  CapsuleDB.Registry("domainkit-storage", {
    url,
    provider: "Postgres",
    manifest,
  });
// Pass registry.fingerprint into the function's version-scoped environment.

函数靴与 readiness: "first-use"数字 :

PgStorage.layer({ mode: "assert", readiness: "first-use" });

该图层构建时没有语句;第一个存储查询运行一个缓存检查. 检查失败 表面为 SqlError 在询问中,然后在下一个重审。 传出同样的 prefix 财务报告和审定财务报表 registryPrefix 改为 manifest 财务报告和审定财务报表 layer。 。 。 .

表格

图表密钥持有
domainkit_authorizationsid供应商授权、账户标签、能力、撤销状态、密封证书
domainkit_connectionsid委托人处理一项授权
domainkit_attachmentsid专用 (owner_id, domain)域、 区域、 提供者目标
domainkit_continuationsidtTL 交互式流量状态
domainkit_attemptsid计划、批准、接收、状况、租赁、失败
domainkit_readiness(owner_id, domain)最新观察、必要证据、退后
domainkit_batchesid专用 (owner_id, idempotency_key)批量状态、核准摘要、拒绝
domainkit_batch_items(batch_id, attachment_id)一个域在批次中的位置:位置、尝试指针、计划失败

批量物品是一个指针: 计划,批准,接收,租赁,失败 它显示一个客户全部 使用它的名字,所以没有存储两次, 批量状态重算从 在交易中试图移动它.

准备状态按域而不是附件键,所以仅观察公共 DNS 的宿主就会得到 同一行; attachment_id 当附件存在时链接, 当附件被清除时链接 已删除.

每张桌子都带着 owner_id,并按 Principal.Service 您的主机提供,所以 属于另一个租户的行读作缺席。 表格上没有外国密钥 之间; 在释放的 SQL 中添加您想要的 .

PgStorage.layer({ prefix }) 重新命名表格。 前缀是物理布局的一部分: 它 更改已生成的 DDL 和迁移校验和, 因此在第一次部署前修好, 永远不要 之后再换. registryPrefix capsuleDB 自己的分类账表格也这样做,必须匹配 capsuledb emit --prefix。 。 。 .

它的保证

  • 总的过渡——核准、索偿、完成、失败、能力提升、证书 替换——在一个交易中运行于 a FOR UPDATE 排队.
  • 续作由 DELETE ... RETURNING,因此重播 OAuth 回调失败 NotFound 而不是连接两次.
  • 撤销为两相:标记 pending,然后删除 仅保留被撤销的证书。 相撞之间,或 刷新旋转证书的中途, 留下一行 recoverRevocations 稍后结束, 所以,新颁发的证书 永远不会成为提供者的孤儿.
  • withLock 使用保留连接的会话咨询锁定失败 Busy 而不是说 等待,所以一个证书刷新单飞 没有持有交易 通过一个HTTP呼叫.

包裹通过 Testing.conformance.storage 从 domainkit/testing,同一个套房 备忘录执行证.

版本与发布记录

@domainkit/capsuledb 共发布 25 个版本,首次发布于 2026/09/01;过去 12 个月发布了 25 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.23.0latest2026/11/0310 天前
0.22.12026/11/0112 天前
0.22.02026/10/2717 天前
0.21.02026/10/091 个月前
0.20.12026/10/051 个月前
0.20.02026/10/031 个月前

其他发布通道:temp → 0.0.0-tegami-trusted-publish-setup。

关于 @domainkit/capsuledb 的常见问题

@domainkit/capsuledb 是什么?

在 PostgreSQL 上作为一个声明式 CapsuleDB 胶囊的域Kit 存储

如何安装 @domainkit/capsuledb?

在项目目录运行 npm install @domainkit/capsuledb,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:effect(>=4.1.2 <5.0.0)、capsuledb(>=0.6.0 <0.7.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@domainkit/capsuledb 支持 TypeScript 吗?

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

@domainkit/capsuledb 支持 ESM 还是 CommonJS?

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

@domainkit/capsuledb 需要什么版本的 Node.js?

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

@domainkit/capsuledb 可以商用吗?

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

@domainkit/capsuledb 的下载量有多少?

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

@domainkit/capsuledb 还在维护吗?

最新版本 0.23.0 发布于 2026/11/03(10 天前);至今共发布 25 个版本,其中过去 12 个月发布了 25 个;首次发布于 2026/09/01。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。