This repository has been archived on 2026-06-01. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
nerve/docs/coding-conventions.md
T
xiaoju fc7fc9158c docs: update all docs/conventions for stateful sense, remove stale refs
Phase 4 of RFC #308: Stateful Sense refactor.

- CLAUDE.md: updated diagram, tables, examples (no more Signal)
- Cleaned stale Signal Bus / DrizzleDB / _signals / retention refs
  across READMEs, .cursor rules, copilot instructions, .knowledge
- Removed drizzle-orm from core package.json (no longer used)
- Updated pnpm-lock.yaml

Refs #308
2026-05-01 10:09:01 +00:00

192 lines
4.7 KiB
Markdown

# Nerve Coding Conventions
## 语言与范式
### 函数式优先
`function` + `type`,不用 `class` + `interface`
```typescript
// ✅ Good
type WorkflowLaunch = {
senseName: string
workflowName: string
ts: number
}
function recordWorkflowLaunch(senseName: string, workflowName: string): WorkflowLaunch {
return { senseName, workflowName, ts: Date.now() }
}
// ❌ Bad
interface IWorkflowLaunch {
senseName: string
workflowName: string
ts: number
}
class WorkflowLaunch implements IWorkflowLaunch {
constructor(
public senseName: string,
public workflowName: string,
public ts: number,
) {}
}
```
### 具体规则
| 规则 | 说明 |
|------|------|
| `type` over `interface` | 所有类型定义用 `type`,不用 `interface` |
| `function` over `class` | 用纯函数 + 闭包,不用 class |
| 无 `this` | 函数不依赖 `this` 上下文 |
| 无继承 | 不用 `extends``implements``abstract` |
| 组合优先 | 用函数组合代替继承层次 |
| 不可变优先 | 用 `Readonly<T>``as const`,避免 mutation |
| 禁用 optional properties | 不用 `?:`,用 `T \| null` 显式标记可空;多个互斥字段用 discriminated union |
### 禁用 Optional Properties
不使用 `?:`,所有可空字段显式标注 `T | null`
```typescript
// ✅ Good — 明确表达"可以为空"
type SenseConfig = {
group: string;
throttle: string | null;
timeout: string | null;
}
// ❌ Bad — optional 隐藏了"缺失"和"空值"的区别
type SenseConfig = {
group: string;
throttle?: string;
timeout?: string;
}
```
当多个字段互斥时,用 discriminated union 代替一堆 optional:
```typescript
// ✅ Good — 编译器保证两种 overflow 形态互斥且字段完整
type WorkflowConfig =
| { concurrency: number; overflow: "drop" }
| { concurrency: number; overflow: "queue"; maxQueue: number }
// ❌ Bad — 字段一堆 optional,运行时才知道到底填了哪种并发策略
type WorkflowConfig = {
concurrency?: number;
overflow?: string;
maxQueue?: number;
}
```
### 例外
以下场景允许 class:
- 第三方库要求(如 Drizzle 的 `sqliteTable` 返回值)
- Error 子类(`class NerveError extends Error`
## 模块与导出
```typescript
// ✅ Named exports only
export function startEngine(config: EngineConfig): Engine { ... }
export type EngineConfig = { ... }
// ❌ No default exports
export default function startEngine() { ... }
```
- 一律 named export,不用 default export
- 一个模块做一件事,文件名即职责
## 命名
| 类型 | 风格 | 示例 |
|------|------|------|
| 文件 | kebab-case | `sense-scheduler.ts` |
| 类型 | PascalCase | `SenseScheduler` |
| 函数/变量 | camelCase | `createSenseScheduler` |
| 常量 | UPPER_SNAKE | `MAX_RETRY_COUNT` |
| 泛型参数 | 单字母或描述性 | `T`, `TValue` |
## 错误处理
```typescript
// ✅ 用 Result 类型表达可预期的失败
type Result<T, E = Error> = { ok: true; value: T } | { ok: false; error: E }
function parseSenseConfig(raw: unknown): Result<SenseConfig> {
// ...
}
// ✅ throw 只用于不可恢复的 bug
function unreachable(x: never): never {
throw new Error(`Unreachable: ${x}`)
}
```
- 可预期的失败用 `Result` 类型返回
- `throw` 只用于 bug(程序员错误),不用于业务逻辑
- 不用 try-catch 做流程控制
## 异步
```typescript
// ✅ async/await,不用 .then() 链
async function runCompute(sense: SenseModule): Promise<Signal | null> {
const value = await sense.compute(db, peers)
if (value == null) return null
return createSignal(sense.id, value)
}
```
## 工具链
| 工具 | 用途 |
|------|------|
| **pnpm** | 包管理 |
| **TypeScript** | 类型检查(strict mode) |
| **Biome** | lint + format(替代 ESLint + Prettier) |
| **tsup** | 打包 |
### 常用命令
```bash
pnpm run check # biome check(lint + format 检查)
pnpm run format # biome format --write(自动修复格式)
pnpm run build # 全量构建
```
## Monorepo 结构
```
nerve/
packages/
core/ # @nerve/core — 共享类型和工具函数
cli/ # @nerve/cli — CLI 入口
daemon/ # @nerve/daemon — 引擎运行时
docs/ # RFC、convention 等文档
biome.json # 根级 Biome 配置
tsconfig.json # 根级 TypeScript 配置(composite project references)
```
- `core` 是共享层,`cli``daemon` 都依赖它
- `cli``daemon` 之间不互相依赖
- 未来云端版本作为新 package 加入
## Commit Convention
```
<type>(<scope>): <description>
type: feat | fix | refactor | docs | chore | test
scope: core | cli | daemon | rfc-001 | ...
```
---
*小橘 🍊(NEKO Team)*