跳至主要内容

生态 ​

battery 是 s200 的中间件复用单元:一个藏在自己专属包入口后面的 opt-in 模块,输入选项、输出 Middleware(完整契约见 编写 Battery)。 本页就是注册表——盒子里装了什么,以及一个第三方 battery 如何加入这份 名单。

官方 ​

下面的一切都随 s200 包本身发布:每个入口一个源文件,以 import { … } from 's200/<entry>' 导入——拉取一个入口绝不拉取另一个。 除 s200/events 外,所有入口都是零运行时依赖;s200/events 构建在 @for-fun/event-emitter 之上(这是它唯一的依赖——核心保持零依赖)。 各入口体积由仓库的 size-limit 预算(pnpm size)按 release 追踪。

中间件 ​

入口提供什么
s200/corscors —— 预检就地应答,头在 unwind 时盖章(含回退)
s200/loggerlogger —— 每请求一行,每个请求都有(含 500)
s200/request-idrequestId —— 播下一个 id,在 unwind 时盖章 x-request-id
s200/timeouttimeout —— 收窄 ctx.signal,让链与截止时间赛跑
s200/etagetag —— 对字节背书的响应体做 If-None-Match 再验证
s200/compresscompress —— 经 CompressionStream 的 gzip/deflate/br
s200/secure-headerssecureHeaders —— OWASP 头集合
s200/cachecache —— 带新鲜度校验器的响应缓存
s200/rate-limitrateLimit —— 滑动窗口限流器,存储可注入
s200/trust-proxytrustProxy —— 代理之后如实还原客户端 IP
s200/versionapiVersion —— header/Accept API 版本门,ctx.state.version
s200/alsals、currentCtx —— 经 node:async_hooks 的环境 ctx(node/bun;非 edge)

认证与会话 ​

入口提供什么
s200/authbasicAuth、bearerAuth —— 带质询的门
s200/jwtsignJwt、verifyJwt、jwtAuth —— 基于 WebCrypto 的 JWS
s200/oauthcreatePkcePair、buildAuthorizeUrl、exchangeCode —— OAuth2 授权码 + PKCE 原语
s200/csrfcreateCsrf —— 双提交令牌
s200/sessioncreateSession —— cookie 会话,存储可注入
s200/cookiesgetCookie、setCookie、getSignedCookie、setSignedCookie

请求体与流式 ​

入口提供什么
s200/acceptsaccepts —— RFC 9110 内容协商
s200/queryparseQuery、queryParams —— 类型化 query 字符串
s200/validatevalidate、jsonBody —— schema 或手写解析函数
s200/serializeserialize、jsonRaw —— 声明式响应形状
s200/multipartstreamForm —— 流式 multipart 部件,逐部件回调
s200/uploaduploadForm —— 门控上传,写入注入的 sink
s200/streamingstream、streamSSE —— 流式与 SSE 响应

实时 ​

入口提供什么
s200/websocketupgradeWebSocket —— 运行时中立的 WS upgrade
s200/websocket/nodecreateUpgradeHandler —— node http 服务器一侧
s200/websocket/buncreateBunWebSocketBridge —— Bun 一侧
s200/websocket/cloudflarecreateCloudflareWebSocketBridge —— Workers 一侧

内省与工具 ​

入口提供什么
s200/route-tablecreateRouteTable —— 应用导出为 JSON,无需执行
s200/metadescribeRoute、describeApp —— 路由注解
s200/openapiopenapiSpec、openapiJson —— OpenAPI 3.1 文档
s200/swaggerswaggerUi —— 提供文档 UI
s200/codegengenerateClient —— 从路由表生成类型化客户端
s200/clientcreateClient —— 类型化 fetch 客户端
s200/testrequest、testClient、probeApp —— 进程内驱动应用
s200/oteltrace —— 每请求的 OTel span
s200/devcreateHotApp、importFresh、watchAndReload、routeHints —— 热路由表与开发期 404 提示

运维 ​

应用生命周期层——NestJS 的 enableShutdownHooks、Terminus、 @nestjs/config、@nestjs/schedule 与 EventEmitter 支持,以 数据 + 函数的形式:

入口提供什么
s200/lifecyclelifecycle —— 信号驱动的优雅关停:翻转就绪态、停止监听、排空在途请求、执行清理
s200/healthhealth、readiness、createGate —— 基于可注入检查的存活/就绪探针
s200/configparseEnv、createConfig —— Standard Schema 定型、快速失败的配置
s200/schedulecreateScheduler、nextRun —— cron(5 字段)与间隔任务,时钟可注入
s200/eventscreateBus —— 基于 @for-fun/event-emitter 的类型化事件总线(同步 emit、emitAsync)

分片与伸缩 ​

水平伸缩层——一个应用,按单元分区,分发接缝保持运行时中立:

实验性(experimental)。 本表全部五个入口都是实验性的:它们的 API 在任意 minor 中都可能变更或撤回,尚未经过生产环境的实战检验,且线程 executor 快速路径依赖 Node 内部的监听器传递行为(Node ≥26.6)。

入口提供什么
s200/shardpolicy、shardSpecs、shardApp、matchShard —— 路由策略注解、可序列化的分片描述符、分区与分发接缝
s200/gatewaynginxConf、gatewayRoutes、albRules —— 纯生成器:同样的描述符 → nginx.conf / Gateway API HTTPRoute / ALB 监听规则
s200/shard-devcreateDispatcher —— 相同前缀语义的进程内分发器 —— 无需 nginx 的本地对等
s200/executorrunShards —— 执行器(inline / thread / process / external)+ supervisor:Node ≥26.6 监听器传递的惰性线程生成、fork 进程 shim、带退避的重启
s200/unit-metricscreateUnitMetrics、unitMetricsEndpoint —— 调度器的眼睛:在途数、队列深度、事件循环利用率、RSS、冷热 —— 作为中间件 + 端点

完整指南:分片与调度。

运行时适配器 ​

不是中间件——每条一行,把同一个应用跑在另一个运行时上:

入口提供什么
s200/nodeserve(light 模式、TLS/HTTP2、WSS upgrade)+ 文件读取器
s200/bunserve + Bun 文件读取器
s200/cloudflarecreateHandler —— module worker 的 default 导出

配方 ​

仓库级 TypeScript,刻意不作为包导出——把文件 vendor 进来,自带 客户端,注入:

配方用途
recipes/redis-stores.ts经 Redis 共享的 rateLimit/createSession 存储——完整指南:分布式存储
recipes/oidc.tscreateOidc —— 基于 s200/cookies/jwt/session 的 OIDC 授权码 + PKCE(S256)登录——完整指南:OIDC 登录

battery 创意 —— 好的上手贡献 ​

官方 battery 刻意保持精简。下面的清单是注册表乐于看到第三方发布的 东西——没有一项在官方路线图上;每个创意都经由既有入口的公开接缝 (选项对象、可注入存储、Middleware 组合)扩展它,标准的 提交模板对每一项都适用。

  • cron 别名与“日/星期”扩展(@daily、L、W),扩展 s200/schedule —— 已发布的解析器是严格的 5 字段 cron。
  • OpenTelemetry logs 信号 + OTLP exporter,扩展 s200/otel —— 已发布的入口零依赖、tracer/meter 可注入;线上协议 exporter 正是 “带依赖也可收录”的教科书案例。
  • 更多 Scalar 文档旋钮(布局、暗色模式默认值、自定义 CSS),扩展 s200/swagger —— 超出已发布的 url/title/theme/cdn 选项。
  • OAuth 提供方(GitHub、Google 等),构建于 s200/oauth + s200/session 之上 —— 已发布的 s200/oauth 覆盖 PKCE/授权 URL/token 交换原语;完整的通用 OIDC 登录流程是上面的 recipes/oidc.ts 配方,s200/auth 覆盖带质询的基础认证。
  • 更多面向 s200/session 与 s200/rate-limit 的共享存储 —— Postgres、SQLite 等,沿 recipes/redis-stores.ts 配方确立的可注入存储接缝(Redis 已在其中覆盖)。
  • s200/accepts 之上的 locale 回退链 —— 已发布的 accepts().language() 在给定标签中选最优;BCP 47 区域回退与 Intl 感知的匹配是自然的延伸。

提交你的 battery ​

下面的注册表面向第三方 battery——任何遵循 battery 契约、可被导入的 东西。提交之前,先看看上面某个官方入口是否已经覆盖了它;更小的核心 配上一圈健康的生态,这才是本意。

收录标准 ​

  • 数据 + 函数范式。 工厂接收选项并返回一个 Middleware(或 数据)——没有类、没有 this、没有模块级注册副作用。 编写 Battery 用内建 battery 的例子讲解两种运行时形态(门与 unwind 盖章器)。
  • 可 tree-shaking。 每个能力一个入口,ESM,无副作用的模块作用域—— 导入你的 battery 不得拉取导入方没有点名的东西。
  • 首选零运行时依赖。 其余一切都是 Web 标准或由调用方注入(存储、 schema、时钟、校验器、sink)——内建 battery 正是因此保持零依赖。 带依赖的 battery 仍可收录;依赖列的存在就是为了让导入方看到成本。
  • 诚实的体积。 你那一行的数字是该入口被导入方实际拉取时的 gzip 字节成本(如 size-limit,或 gzip -9 < dist/entry.mjs | wc -c),是测出来的,不是估出来的。

提交模板 ​

向本页开一个 PR,按此模板向注册表添加一行:

md
| Name | Entry | Depends on | Size (gz) | Notes |
| ---- | ----- | ---------- | --------- | ----- |
| your-battery | `your-battery` | — | 0.4 kB | one line: what it does, and which seam it plugs (gate / unwind stamper / data) |
  • Name —— npm 包名,如果你希望该命名空间被读作一种生态惯例,可加 s200-battery- 前缀(非必需)。
  • Entry —— 导入方书写的子路径,如 s200-battery-og/image(每入口 一行;多入口包每个入口各一行)。
  • Depends on —— 运行时依赖,无则 —。peer 依赖也计入,并附版本 范围。
  • Size (gz) —— 实测的入口 gzip 体积(见上面的标准)。
  • Notes —— 一行,现在时:它做什么。在 Name 单元格里链接仓库文档。

流程 ​

  1. 按编写 Battery 指南编写;随附测试和带实测体积的 README。
  2. 开一个 PR 把你的行加进下面的注册表——表格就是评审面,PR 落地 即上架。
  3. 包不再可解析、或体积漂移且未沟通的行,会先收到一个提醒 PR,随后 被移除。

注册表——第三方 battery ​

NameEntryDepends onSize (gz)Notes

该表刻意从空开始——没有占位行。每个单元格遵循上面的提交模板;第一个 真实条目将确立先例。

基于 MIT 许可证发布。