# @datafn/server 中文文档

规范地址：https://npmcn.com/package/%40datafn/server/

版本：0\.2\.1
npm 元数据更新时间：2026-11-11T07:55:41.818Z
中文译文更新时间：2026-11-11T14:34:04.190Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40datafn/server
原文对照：https://npmcn.com/package/%40datafn/server/?lang=original
项目主页：https://github.com/21nCo/superfunctions#readme
源码仓库：https://github.com/21nCo/superfunctions

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

- 包体积（解压后）：5.5 MB，14 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=18\.18\.0
- 运行依赖：4 个
- 首次发布：2026-03-14T18:30:55.118Z
- 最新版本发布：2026-11-11T07:55:41.455Z
- 近 30 天下载量：3201（2026-10-12 至 2026-11-10，npm 官方下载统计）
- 已发布版本数：8（近 12 个月 8 个）

## 中文简介

DataFn 服务器运行时间 - DFQL 查询、变异和同步的 HTTP 端点

## 安装

```sh
npm install @datafn/server
```

也可以使用：`pnpm add @datafn/server`、`yarn add @datafn/server`、`bun add @datafn/server`

## README

# @ datafn/ 服务器

DataFn的HTTP服务器运行时间. 提供DFQL查询执行,以一能和乐观的相通性进行突变,原子交易,完全双向同步(clone/pull/push/reconcile/seed),每个用户/租户隔离,REST端点生成,WebSocket实时更新,插件钩,可配置限制.

## 安装

```bash
npm install @datafn/server @datafn/core @superfunctions/db @superfunctions/http @superfunctions/http-hono hono @hono/node-server
```

## 特征

| 特性 | 说明 |
| --- | --- |
| **查询执行** | DFQL 有过滤、排序、页码、关系、聚合等查询 |
| **变异** | CRUD 具有一能性(`clientId` + 键 `mutationId` 减值)和乐观货币(`if` 警卫) |
| **关系操作** | `relate`, (中文(简体) ), `unrelate`, (中文(简体) ), `modifyRelation` 用于多种关系类型和其他关系类型 |
| **交易** | 有查询+变异步骤的原子多步操作 |
| **同步: 克隆** | 初始水合的全部数据下载 |
| **同步: 拉** | 基于光标的递增更改同步 |
| **同步: 推** | 从客户端更改日志上传下线突变 |
| **同步: 调和** | 探测并解决地上/远地漂流 |
| **同步:种子** | 种子数据输入数据库 |
| **授权** | 行动授权钩 |
| **多用户隔离** | 用于跟踪变化的用户/租户命名空间隔离 |
| **多区域网关** | 原租户的安置、执行前的牢房围栏、经签名的内部转发、有限度地重新试验和控制下的行动 |
| **REST 终点** | 在DFQL(GET/POST/PATCH/DELETE)上可选 REST包装器 |
| **网络安全套** | 实时光标进行实时更新 |
| **插件** | 连接查询、突变和同步到服务器侧 |
| **序列存储** | 可插件服务器Seq后端:数据库, Redis, KV, 或连锁商店 |
| **有效载荷限制** | 可配置的最大查询限制、交易步骤和有效载荷大小 |
| **KV 资源** | 内置的密钥值资源自动包含在计划内 |

多区域网关模式是可选入的,并保持所有权与 权限指令投影。 见 [`multi-region-gateway.mdx`](https://npmcn.com/package/%40datafn/docs/content/docs/documentation/multi-region-gateway.mdx) 用于配置、错误、 WebSocket、一致性、迁移和操作 合同.

### 初步地区安置

DataFn 在不嵌入产品数据的情况下提供可重复使用的区域选择 居住或能力政策:

```typescript
import {
  readDatafnCloudflarePlacementLocation,
  selectDatafnPlacementRegion,
} from "@datafn/server/placement";

const decision = selectDatafnPlacementRegion({
  candidates: regions,
  location: readDatafnCloudflarePlacementLocation(request),
  constraints: [
    (region) => allowedRegionIds.includes(region.regionId),
    (region) => healthyRegionIds.has(region.regionId),
  ],
});
```

符合条件的明确偏好先取胜, 信任的坐标或大陆 元数据按距离排列其余区域,可选 `stableKey` 能够确定后退。 返回的决定记录是 已使用。 申请仍负责界定合格区域,收集 明确组织选择,并解剖性地声称由此产生的命名空间 通过放置目录.

* * *

## 快速启动

```typescript
import { createDatafnServer } from "@datafn/server";
import { drizzleAdapter } from "@superfunctions/db/adapters";
import { toHono } from "@superfunctions/http-hono";
import { Hono } from "hono";
import { serve } from "@hono/node-server";

const server = await createDatafnServer({
  schema: {
    resources: [
      {
        name: "tasks",
        version: 1,
        fields: [
          { name: "id", type: "string", required: true, unique: true },
          { name: "title", type: "string", required: true },
          { name: "completed", type: "boolean", required: true, default: false },
        ],
      },
    ],
  },
  database: drizzleAdapter({ db: myDrizzleInstance, dialect: "postgres" }),
  authorize: async (ctx, action, payload) => {
    return true; // Allow all (replace with real logic)
  },
});

const app = new Hono();
app.route("/", toHono(server.router));
serve({ fetch: app.fetch, port: 3000 });
```

* * *

## 配置

### 数据fnServer 配置

```typescript
interface DatafnServerConfig<TContext = any> {
  /** DataFn schema — validated and normalized at startup */
  schema: DatafnSchema;

  /** Database adapter (e.g. drizzleAdapter, memoryAdapter) */
  database?: Adapter;

  /** Server-side plugins */
  plugins?: DatafnPlugin[];

  /**
   * Authorization callback. Called on every request after JSON parsing.
   * Return true to allow, false to reject with 403 FORBIDDEN.
   */
  authorize?: (
    ctx: TContext,
    action:
      | "status" | "query" | "mutation" | "transact"
      | "seed" | "clone" | "pull" | "push" | "reconcile",
    payload: unknown,
  ) => Promise<boolean> | boolean;

  /** Static request context or a request-scoped context factory. */
  context?: TContext | ((request: Request) => Promise<TContext> | TContext);

  /** Configurable limits */
  limits?: {
    /** Maximum number of records per query (default: 100) */
    maxLimit?: number;
    /** Maximum transaction steps */
    maxTransactSteps?: number;
    /** Maximum request body size in bytes */
    maxPayloadBytes?: number;
  };

  /** Custom server time provider (for testing) */
  getServerTime?: () => number;

  /**
   * Enable REST endpoint generation.
   * When true, generates REST wrappers alongside DFQL endpoints.
   */
  rest?: boolean;

  /**
   * Auth context provider for per-user/tenant isolation.
   * Extracts user/tenant context from request to create isolated namespaces.
   */
  authContextProvider?: {
    getContext: (ctx: TContext) => AuthContext | Promise<AuthContext>;
  };

  /** Trusted namespace and optional actor derivation from request context. */
  namespaceProvider?: {
    getNamespace: (ctx: TContext) => string | Promise<string>;
    getActorId?: (ctx: TContext) => string | undefined | Promise<string | undefined>;
  };

  /**
   * Redis adapter for atomic operations (serverSeq, rate limiting, caching).
   * Used when dbMapping.serverseq = "redis".
   */
  redis?: RedisAdapter;

  /**
   * KV store adapter for simple key-value operations.
   * Must support incr() for serverSeq. Used when dbMapping.serverseq = "kv".
   */
  kvStore?: KVStoreAdapter;

  /**
   * Database mapping — choose which backend for each concern.
   * Default: main database for everything.
   */
  dbMapping?: DbMapping;
}
```

### 绘图

将不同的服务器关切运行到不同的后端 :

```typescript
type DbMapping = {
  /** Backend for serverSeq counter: "db" | "redis" | "kv" */
  serverseq?: "db" | "redis" | "kv";
  /** Backend for rate limiting */
  ratelimiting?: "db" | "redis" | "kv";
  /** Backend for caching */
  cache?: "db" | "redis" | "kv";
};
```

* * *

## 终点

### 获取/datafn/状态

服务器健康检查,计划散列,能力和限制.

```json
{
  "ok": true,
  "result": {
    "schemaHash": "a1b2c3...",
    "capabilities": [
      "dfql.query", "dfql.mutation", "dfql.transact",
      "sync.seed", "sync.clone", "sync.pull", "sync.push", "sync.reconcile"
    ],
    "limits": { "maxLimit": 100 },
    "serverTimeMs": 1707000000000
  }
}
```

### POST / 数据fn/克瑞

执行 DFQL 查询,包括全过滤、排序、页码和关系扩展.

**请:**

```json
{
  "resource": "tasks",
  "version": 1,
  "select": ["id", "title", "completed"],
  "filters": { "completed": false },
  "sort": ["title:asc"],
  "limit": 20
}
```

**回应:**

```json
{
  "ok": true,
  "result": {
    "data": [
      { "id": "task:1", "title": "Buy milk", "completed": false }
    ],
    "nextCursor": null
  }
}
```

**过滤操作符 :**

| 运算符 | 示例 | 说明 |
| --- | --- | --- |
| `eq` (隐含) | `{ "status": "active" }` | 等数 |
| `eq` (解释性) | `{ "status": { "eq": "active" } }` | 等数 |
| `ne` | `{ "status": { "ne": "archived" } }` | 不等于一个 |
| `gt` 编号 : `gte` | `{ "age": { "gt": 18 } }` | 大于 / 或相等 |
| `lt` 编号 : `lte` | `{ "age": { "lt": 65 } }` | 小于/或等值 |
| `like` | `{ "name": { "like": "%john%" } }` | 对大小写敏感的模式匹配 |
| `ilike` | `{ "name": { "ilike": "%john%" } }` | 大小写模式匹配 |
| `is_null` | `{ "deletedAt": { "is_null": true } }` | 无效 |
| `is_not_null` | `{ "email": { "is_not_null": true } }` | 不为空 |
| `in` | `{ "status": { "in": ["active", "pending"] } }` | 设定 |
| `nin` | `{ "status": { "nin": ["archived"] } }` | 未设定 |
| `contains` | `{ "tags": { "contains": "urgent" } }` | 阵列/ JSON 包含 |

**逻辑组 :**

```json
{
  "$or": [
    { "status": "active" },
    { "priority": { "gte": 4 } }
  ]
}
```

### POST /数据fn/搜索

通过配置的服务器执行跨资源搜索 `searchProvider`。 。 。 .

**请:**

```json
{
  "query": "test",
  "resources": ["tasks", "projects"],
  "limit": 20,
  "prefix": true,
  "fuzzy": 0.2,
  "fieldBoosts": { "title": 2, "name": 1 }
}
```

**回应:**

```json
{
  "ok": true,
  "result": {
    "results": [
      { "resource": "tasks", "id": "task:1", "score": 12.34, "data": {} }
    ]
  }
}
```

与客户端路径的搜索选项均等 :

-   `prefix` 启用前缀匹配 .
-   `fuzzy` 允许模糊匹配 .
-   `fieldBoosts` 应用字段级加权.

这些选项在路由/平流边界被验证后被传送到提供者执行.

**汇总查询 :**

```json
{
  "resource": "tasks",
  "version": 1,
  "groupBy": ["status"],
  "aggregations": {
    "count": { "fn": "count" },
    "avgPriority": { "fn": "avg", "field": "priority" }
  },
  "having": { "count": { "gt": 5 } }
}
```

### POST/数据fn/计算

以一能和乐观的货币来执行突变.

**插入:**

```json
{
  "resource": "tasks",
  "version": 1,
  "operation": "insert",
  "clientId": "client:device-1",
  "mutationId": "m-001",
  "record": { "title": "New task", "completed": false }
}
```

**合并( 部分更新) :**

```json
{
  "resource": "tasks",
  "version": 1,
  "operation": "merge",
  "clientId": "client:device-1",
  "mutationId": "m-002",
  "id": "task:abc",
  "record": { "completed": true }
}
```

**删除:**

```json
{
  "resource": "tasks",
  "version": 1,
  "operation": "delete",
  "clientId": "client:device-1",
  "mutationId": "m-003",
  "id": "task:abc"
}
```

**乐观货币( 如果是警卫):**

```json
{
  "resource": "tasks",
  "version": 1,
  "operation": "merge",
  "id": "task:abc",
  "record": { "status": "completed" },
  "if": { "status": "in_progress" }
}
```

变异被拒绝 `CONFLICT` 如果看守条件没有得到满足.

**关系业务:**

```json
{
  "resource": "tasks",
  "version": 1,
  "operation": "relate",
  "id": "task:1",
  "relation": "tags",
  "targetId": "tag:urgent"
}
```

| 运行 | 说明 |
| --- | --- |
| `relate` | 在记录之间建立关系 |
| `unrelate` | 删除关系 |
| `modifyRelation` | 更新关系元数据 |

**回应:**

```json
{
  "ok": true,
  "result": {
    "ok": true,
    "mutationId": "m-001",
    "affectedIds": ["task:new-uuid"],
    "errors": [],
    "deduped": false
  }
}
```

-   `deduped: true` 表示已应用了突变(偶发性).

### POST/数据fn/交易

原子多步骤交易混合了询问和突变.

原子执行需要数据库交易. 适配器报告时 `capabilities.transactions.supported === false` (例如SQLite或Cloudflare D1上的Drizzle适配器),一个带有任何变异步骤的原子变换器返回 HTTP 400 与 `DFQL_UNSUPPORTED` (单位:千美元)`details.path: "atomic"`)在任何东西被写入之前. 发送 `"atomic": false` 一次实施步骤一.

**请:**

```json
{
  "transactionId": "tx-batch",
  "atomic": true,
  "steps": [
    {
      "query": {
        "resource": "tasks",
        "version": 1,
        "select": ["id"],
        "filters": { "completed": false }
      }
    },
    {
      "mutation": {
        "resource": "tasks",
        "version": 1,
        "operation": "merge",
        "id": "task:1",
        "record": { "completed": true }
      }
    }
  ]
}
```

**回应:**

```json
{
  "ok": true,
  "result": {
    "ok": true,
    "results": [
      { "kind": "query", "ok": true, "result": { "data": [...] } },
      { "kind": "mutation", "ok": true, "result": { ... } }
    ]
  }
}
```

### POST / 数据fn/ clone

初始水分完全数据下载. 支持帕吉纳克.

**请:**

```json
{
  "version": 1,
  "tables": ["tasks", "categories"]
}
```

**回应:**

```json
{
  "ok": true,
  "result": {
    "ok": true,
    "data": {
      "tasks": [{ "id": "task:1", "title": "..." }],
      "categories": [{ "id": "cat:1", "name": "..." }]
    },
    "cursors": {
      "tasks": "42",
      "categories": "15"
    }
  }
}
```

### POST/数据fn/推

递增同步——仅返回自上个光标后的变化 .

**请:**

```json
{
  "version": 1,
  "cursors": {
    "tasks": "42",
    "categories": "15"
  }
}
```

**回应:**

```json
{
  "ok": true,
  "result": {
    "ok": true,
    "records": {
      "tasks": [{ "id": "task:3", "title": "New since last pull", "__deleted": false }]
    },
    "cursors": {
      "tasks": "44",
      "categories": "15"
    }
  }
}
```

### POST/数据fn/推

从客户端更改日志上传下线突变.

**请:**

```json
{
  "version": 1,
  "mutations": [
    {
      "resource": "tasks",
      "version": 1,
      "operation": "insert",
      "clientId": "client:device-1",
      "mutationId": "m-offline-1",
      "record": { "title": "Created offline" }
    }
  ]
}
```

### POST /数据fn/调节

探测并解决本地和偏远地区之间的漂移.

**请:**

```json
{
  "version": 1,
  "counts": {
    "tasks": 42,
    "categories": 8
  }
}
```

### POST /数据fn/种子

种子数据输入数据库.

**请:**

```json
{
  "data": {
    "tasks": [
      { "id": "task:seed-1", "title": "Seeded Task", "completed": false }
    ]
  }
}
```

* * *

## 多用途/多用途隔离

按用户或租户单独跟踪变化情况。 每个命名空间都有自己的 `serverSeq` 计数器,确保用户只看到自己的修改.

```typescript
const server = await createDatafnServer({
  schema,
  database: adapter,
  authContextProvider: {
    getContext: (ctx) => ({
      userId: ctx.session?.userId,
      tenantId: ctx.session?.tenantId,
    }),
  },
});
```

**命名空间格式 :**

-   无认证 : `datafn` (默认)
-   单租户: `user:${userId}`
-   多租户: `tenant:${tenantId}:user:${userId}`

**行为:**

1.  每一个要求, `authContextProvider.getContext(ctx)` 名为
2.  命名空间来源于 `userId` 和可选 `tenantId`
3.  所有更改跟踪( 服务器Seq, 更改记录) 都使用此命名空间
4.  Pull/ clone 只返回用户命名空间的更改
5.  若为 `getContext()` 失败, 回到默认状态 `datafn` 命名空间

* * *

## 序列存储

服务器使用 `SequenceStore` 用于生成单调增序数。 选择适合您的基础设施的后端 :

```typescript
// Default: use main database
const server = await createDatafnServer({
  schema,
  database: adapter,
});

// Redis for high-throughput atomic INCR
const server = await createDatafnServer({
  schema,
  database: adapter,
  redis: myRedisAdapter,
  dbMapping: { serverseq: "redis" },
});

// KV store (e.g. Cloudflare KV, DynamoDB)
const server = await createDatafnServer({
  schema,
  database: adapter,
  kvStore: myKVAdapter,
  dbMapping: { serverseq: "kv" },
});
```

**可用的执行:**

| 存储 | 后端 | 最好还是 |
| --- | --- | --- |
| `DatabaseSequenceStore` | 主数据库 | 简单部署 |
| `RedisSequenceStore` | 重写 | 高吞吐量,原子内核 |
| `KVSequenceStore` | KV 存储 | 无服务器环境 |
| `ChainedSequenceStore` | 链条 | 初级+数据库链(例如Redis → DB) |

### 创建序列Store( 配置)

创建适当商店的工厂 `dbMapping`数字 :

```typescript
import { createSequenceStore } from "@datafn/server";

const store = createSequenceStore({
  db: myAdapter,
  redis: myRedisAdapter,
  dbMapping: { serverseq: "redis" },
});
```

* * *

## REST 终点( 可选)

启用 DFQL 端点旁的 REST 包装器 :

```typescript
const server = await createDatafnServer({
  schema,
  database: adapter,
  rest: true, // Enable REST endpoints
});
```

**生成路线 :**

| 方法 | 路径 | 地图到 |
| --- | --- | --- |
| 获取 | `/datafn/resources/:resource` | 查询包装 |
| 邮政 | `/datafn/resources/:resource` | 插入包装 |
| 帕齐 | `/datafn/resources/:resource/:id` | 合并包装 |
| 迪莱特 | `/datafn/resources/:resource/:id` | 删除包装 |

* * *

## 网络安全套

服务器显示一个用于实时光标广播的 WebSocket 处理器:

```typescript
const server = await createDatafnServer({ schema, database: adapter });

// Wire WebSocket connections to server handler
wss.on("connection", (ws) => {
  const client = { id: ws.id, send: (msg) => ws.send(msg) };
  server.websocketHandler.addClient(client);
  ws.on("message", (data) => server.websocketHandler.handleMessage(client, data));
  ws.on("close", () => server.websocketHandler.removeClient(client));
});
```

* * *

## 插件

服务器端插件拦截查询、突变和同步 :

```typescript
const auditPlugin: DatafnPlugin = {
  name: "server-audit",
  runsOn: ["server"],

  afterMutation(ctx, mutation, result) {
    console.log("Server mutation:", mutation);
  },

  beforeSync(ctx, phase, payload) {
    console.log(`Sync ${phase} started`);
    return payload; // Return modified payload or original
  },
};

const server = await createDatafnServer({
  schema,
  database: adapter,
  plugins: [auditPlugin],
});
```

* * *

## 服务器实例

`createDatafnServer` 返回 a `DatafnServer`数字 :

```typescript
interface DatafnServer<TContext = any> {
  /** HTTP router — wire to your framework (Hono, Express, etc.) */
  router: Router<TContext>;

  /** WebSocket handler for real-time updates */
  websocketHandler: {
    addClient(client: WebSocketClient): void;
    removeClient(client: WebSocketClient): void;
    handleMessage(client: WebSocketClient, data: string): void;
  };
}
```

使用 `@superfunctions/http-hono` 或者说 `@superfunctions/http-express` 以挂载路由器 :

```typescript
// Hono
import { toHono } from "@superfunctions/http-hono";
app.route("/", toHono(server.router));

// Express
import { toExpress } from "@superfunctions/http-express";
app.use("/", toExpress(server.router));
```

* * *

## 出口

```typescript
// Server factory and types
export { createDatafnServer }
export type { DatafnServerConfig, DatafnServer }
export type { StatusResult }

// Sequence store
export type { SequenceStore, DbMapping }
export {
  createSequenceStore,
  RedisSequenceStore,
  KVSequenceStore,
  DatabaseSequenceStore,
  ChainedSequenceStore,
}
```

## 许可证

麻省理工学院

## 修复继承的不活动

`recomputeAncestorInactive` 在一个命名空间中扫描已限定的批次; 以 `nextCursor`。 。 。 . `recomputeAncestorInactiveAll` 重复扫描直到验证 扫描找不到更改或跳过比较和设置的写入 。 检查 `converged`· ; `updated: 0` 单靠自己不能证明完成. `skipped` 计数同时写入 冲突。 干运行数不匹配而不写入 .

修复从祖先存档/崩溃状态和关系链接中获取值, 从不存储 `isAncestorInactive` 旗帜。 周期、缺失/畸形父母, 越轨限制的违反会造成明显的错误. `batchSize`, (中文(简体) ), `maxSweeps` 财务报告和审定财务报表 `maxGraphNodes` 必须是正安全整数; `maxGraphNodes` 默认为 每行修补一万个节点。 失败的批次可以安全重放; 之前完成的写作是一能的.

以祖先/链接突变进行修复 比较和设定保护 每个字段来自同时传播的文字;它不提供 所有祖先记录的原子快照 同时恢复和核实 活动在依赖修复的价值进行消费者迁移之前就已解决.

## 常见问题

### @datafn/server 是什么？

DataFn 服务器运行时间 - DFQL 查询、变异和同步的 HTTP 端点

### 如何安装 @datafn/server？

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

### @datafn/server 支持 TypeScript 吗？

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

### @datafn/server 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @datafn/server 需要什么版本的 Node\.js？

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

### @datafn/server 可以商用吗？

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

### @datafn/server 的下载量有多少？

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

### @datafn/server 还在维护吗？

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

