# @12-apps/entity-lifecycle 中文文档

规范地址：https://npmcn.com/package/%4012-apps/entity-lifecycle/

版本：4\.17\.0
npm 元数据更新时间：2026-10-26T20:57:35.756Z
中文译文更新时间：2026-11-05T19:42:03.453Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%4012-apps/entity-lifecycle
原文对照：https://npmcn.com/package/%4012-apps/entity-lifecycle/?lang=original
项目主页：https://github.com/12-apps/shared-packages#readme
源码仓库：https://github.com/12-apps/shared-packages

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

- 包体积（解压后）：359 kB，58 个文件
- 模块格式：ES Module
- TypeScript 类型：未声明
- Node.js 要求：\>=22\.0\.0
- 运行依赖：1 个
- peer 依赖：zod \>=4\.0\.0，hono \>=4\.0\.0，react \>=19\.0\.0，react-dom \>=19\.0\.0，@12-apps/mcp \>=3\.4\.0，@12-apps/wiring \>=1\.3\.0
- 首次发布：2026-08-05T02:17:10.663Z
- 最新版本发布：2026-10-26T20:57:34.762Z
- 近 30 天下载量：33421（2026-10-04 至 2026-11-02，npm 官方下载统计）
- 已发布版本数：58（近 12 个月 58 个）

## 中文简介

通用,可移植的实体-生命周期插件:基于diff的版本历史,包含还原+保留,再生-斌软删除,每个项目草案和更改批准. 无框架核心,主机挂后端表面 (./ server: 版本/再保存/草稿/回收-bin)

## 安装

```sh
npm install @12-apps/entity-lifecycle
```

也可以使用：`pnpm add @12-apps/entity-lifecycle`、`yarn add @12-apps/entity-lifecycle`、`bun add @12-apps/entity-lifecycle`

## README

# @ 12- 应用程序/ 实体- 生命周期

通用、便携式实体寿命周期机械——设计用于任何 项目。 无框架核心,零运行时间依赖,通过适配器存储.

四个功能,每个插件和游戏每集:

| 特性 | 它给你什么 |
| --- | --- |
| **版本** | 基于 Diff 的历史( 仅存储已更改的字段), 恢复到任意版本, 保留政策( 最大计数/ 最大年龄) 有安全压缩 , `publishedVersion` 镜像 |
| **回收桶** | 使用依附者的树登记册软删除,恢复/永久删除 |
| **草稿** | 每个项目(或全新项目)一份未出版的工作副本,公布/丢弃;每集选入:新项目草案更新到位,由作者恢复,30天后被清理(ADOPTING.md QQ新项目草案) |
| **核准** | 由非核准人写作成为待处理的更改请求;核准人申请/拒绝 |

版本、草案和核准 **每名租户可显示特征** 通过a 三层门;一旦一个收藏被插入,循环箱总是被打开.

## 插头和游戏表面(12-17)

下面的核心是内核;主机通常采用整个地表 而不是布线:

-   `@12-apps/entity-lifecycle/server` —— 说 `createApiEntityLifecycle({ db, entities, directory })`: 版本 / 恢复 / 草稿 / 再循环- bin / 每一登记藏品的GENERTED 每个声明,在软件包拥有的4个表格上.
-   `@12-apps/entity-lifecycle/hono` —— 说 `entityLifecycleRouter({ ...config, resolveActor })`,单调挂载(`hono` 是一个可选的对等点).
-   `@12-apps/entity-lifecycle/react` —— 说 `createWebEntityLifecycle({ apiBase, copy })`数字 : lixeira + Aprovações 页面,加上 `VersionHistoryDialog` 财务报告和审定财务报表 `DraftBanner` a 主机滴入到自己的编辑器中.
-   `@12-apps/entity-lifecycle/mcp` —— 说 `lifecycleMcpEndpoints({ collectionPath, noun, summaries })`相同的八种能力 描述一个AGENT, 每集一通电话。 上面的路线已经来自一个 声明;他们的MCP描述是主机仍然写出来的部分 每个收藏一次。 形状是包的,摘要保持 东道主的 (`@12-apps/mcp` 财务报告和审定财务报表 `zod` 是可选的同伴).
-   `prisma/entity-lifecycle.prisma` + 键 `prisma/migrations/*` ——型号 部分和迁移情况,通过 `prisma:sync` 编辑 主机的插件- 迁移同步 .

完全收养合同——配置表,终点清单,规则 和已拥有这些表格的主机的笔记——在 [采用.md](https://npmcn.com/package/%4012-apps/entity-lifecycle/ADOPTING.md)。 。 。 .

## 概念

### 抓图和 diffs

一个实体的版本为 `Snapshot` JSON 其顶级域图 (允许的去除值). 版本 1 存储 FULL 快照; 每个后期版本 仅存储已更改的顶级字段(`data`和已删除的字段 (单位:千美元)`removedFields`) (中文(简体) ). N版的状态通过重放行 1..N来重建 (单位:千美元)`materializeVersion`) (中文(简体) ). 保留修补折叠所覆盖的前缀 最古老的活生生的一行(被推广到一个完整的快照),所以链条总是 复有相会.

### 三层特性门

```
enabled = code (collection opted in)
       && plan (tenant is ENTITLED — what they pay for)
       && tenant (the tenant kept it ENABLED — never forced)
```

主办方按要求解决两个租户层,并通过 `LifecycleContext`图书馆从来不读租户州本身.

**与 `@12-apps/entitlements` (FUT-278,一份有文件记载的决定):** `resolveFeature` 故意呆在这里,没有依赖和同步, 而不是迁移到 `@12-apps/entitlements`' `resolveEntitlement` 那个.. 解析器是它的严格通缩(quotas, overs, a status level),带有 相同的图层顺序、理由字符串和未变换默认 布尔子集 。 迁移会买不到任何可观察到的行为 同时强迫 aync 引擎进入内核同步守护并翻转生命周期写入 从他们的403到引擎的402上升道的否定. 平等 使独立安全 由 `apps/web/lib/entitlements/__tests__/resolver-drift.test.ts`; 主机桥 两国在 `apps/web/lib/entitlements/index.ts` (FUT-326号) 合作赠款工会).

### Schema 更改 vs 恢复( 回滚姿态)

版本存储了松散的JSON,故意与活生生的"计划"脱钩. 打开 恢复,HOST's `applySnapshot` 将存储的快照转换回它的 当前写入模式——丢出未知/存储字段,默认缺失字段, 并重新验证引用。 当前的方案总是获胜; 旧的快照 永远无法写出已经不存在的一栏。 从不指向迁移工具 这些桌子的有效载荷.

## 插入一个收藏

```ts
import {
  createEntityLifecycle,
  type EntityOps,
  type LifecycleStores,
} from '@12-apps/entity-lifecycle';

const productOps: EntityOps = {
  readSnapshot: async (tenantId, id) => /* live state or null */,
  applySnapshot: async (tenantId, idOrNull, snapshot) => /* create/update; return id */,
  archive: async (tenantId, id) => /* soft-hide; boolean */,
  unarchive: async (tenantId, id) => /* undo archive; boolean */,
  hardDelete: async (tenantId, id) => /* permanent */,
  collectChildren: async (tenantId, id) => /* dependents for the bin tree */,
  onVersionRecorded: async (tenantId, id, version) => /* mirror publishedVersion */,
};

export const products = createEntityLifecycle(
  {
    entityType: 'product',
    features: { versioning: true, drafts: true, approvals: true },
    featureDefaults: { approvals: false }, // entitled ⇒ on, except approvals
    label: (s) => String(s.name ?? ''),
    diff: { ignoreFields: ['updatedAt'] },
    retention: { maxVersions: 50, maxAgeDays: 365 },
  },
  stores, // LifecycleStores: your DB-backed adapters (or the in-memory ones)
  productOps,
);
```

每一次突变,然后通过服务漏斗:

```ts
const ctx = { tenantId, actorId, entitlements, settings, canApprove };

await products.create(ctx, snapshot);        // → { status: 'applied' | 'pending-approval' }
await products.update(ctx, id, snapshot);    // records a diff version
await products.softDelete(ctx, id);          // archive + recycle-bin tree
await products.history(ctx, id);             // newest-first summaries
await products.compareVersion(ctx, id, 3);   // v3 beside previous / next / current
await products.restoreVersion(ctx, id, 3);   // replay 1..3, apply, record RESTORE
await products.restoreDeleted(ctx, entryId); // un-archive from the bin
await products.purgeDeleted(ctx, entryId);   // permanent delete
await products.saveDraft(ctx, id, data);     // or (ctx, null, data) for a new item
await products.publishDraft(ctx, draftId);
await products.approveChange(ctx, requestId); // requires ctx.canApprove
```

`canApprove` 是东道主RBAC的决定(例如a) `products:approve` 允许)。 当批准有效时 `canApprove !== true`,创建 / 更新 / 删除 / 恢复 / 作为待决更改请求公布所有 park .

## 存储适配器

**DB 辅助适配器飞船**: 通过任何满意的客户端 结构 `LifecycleDb` 连接( Prisma 客户端直接进行) 到 `createDbLifecycleStores(db)` 从 `@12-apps/entity-lifecycle/server` - 或者让 `createApiEntityLifecycle` 为您建造它们. **普里斯玛模型及其 移民船也一样**数字 : `prisma/entity-lifecycle.prisma` 是犬科动物 4个通用表格部分`entity_versions`, (中文(简体) ), `recycle_bin_entries`, (中文(简体) ), `entity_drafts`, (中文(简体) ), `change_requests`(三); `pnpm --filter @12-apps/entity-lifecycle prisma:sync` 复制到一个多文件的 schema 文件夹( 带有 `--check` 漂移 和迁移情况 `prisma/migrations/` 已发现 由主机的插件- 迁移同步结构 。 这部分是 宿主不可知:租赁是一个可分值 `client_id` scal (在您自己加个 FK 迁移( 如果您想要) 和关闭的套件是带有 CHECK 限制的字符串 在运入的迁移中。 对于自定义商店, 执行 `VersionStore`, (中文(简体) ), `RecycleBinStore`, (中文(简体) ), `DraftStore`, (中文(简体) ), `ApprovalStore`; 模拟执行 用于试验/造型的船舶: `createMemoryVersionStore()` 包括:.

## 测试

```
pnpm --filter @12-apps/entity-lifecycle test
```

## 常见问题

### @12-apps/entity-lifecycle 是什么？

通用,可移植的实体-生命周期插件:基于diff的版本历史,包含还原\+保留,再生-斌软删除,每个项目草案和更改批准\. 无框架核心,主机挂后端表面 \(\./ server: 版本/再保存/草稿/回收-bin\)

### 如何安装 @12-apps/entity-lifecycle？

在项目目录运行 npm install @12-apps/entity-lifecycle，或使用 pnpm add / yarn add / bun add。

### @12-apps/entity-lifecycle 支持 TypeScript 吗？

该包的 package\.json 没有声明类型入口。需要类型提示时，可以在 npm 上查找社区维护的 @types/12-apps\_\_entity-lifecycle 是否存在。

### @12-apps/entity-lifecycle 支持 ESM 还是 CommonJS？

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

### @12-apps/entity-lifecycle 需要什么版本的 Node\.js？

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

### @12-apps/entity-lifecycle 可以商用吗？

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

### @12-apps/entity-lifecycle 的下载量有多少？

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

### @12-apps/entity-lifecycle 还在维护吗？

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

