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

4.7 KiB

Nerve Coding Conventions

语言与范式

函数式优先

function + type,不用 class + interface

// ✅ 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 上下文
无继承 不用 extendsimplementsabstract
组合优先 用函数组合代替继承层次
不可变优先 Readonly<T>as const,避免 mutation
禁用 optional properties 不用 ?:,用 T | null 显式标记可空;多个互斥字段用 discriminated union

禁用 Optional Properties

不使用 ?:,所有可空字段显式标注 T | null

// ✅ Good — 明确表达"可以为空"
type SenseConfig = {
  group: string;
  throttle: string | null;
  timeout: string | null;
}

// ❌ Bad — optional 隐藏了"缺失"和"空值"的区别
type SenseConfig = {
  group: string;
  throttle?: string;
  timeout?: string;
}

当多个字段互斥时,用 discriminated union 代替一堆 optional:

// ✅ 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

模块与导出

// ✅ 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

错误处理

// ✅ 用 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 做流程控制

异步

// ✅ 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 打包

常用命令

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 是共享层,clidaemon 都依赖它
  • clidaemon 之间不互相依赖
  • 未来云端版本作为新 package 加入

Commit Convention

<type>(<scope>): <description>

type: feat | fix | refactor | docs | chore | test
scope: core | cli | daemon | rfc-001 | ...

小橘 🍊(NEKO Team)