关于 effect
effect 是指导开发者使用 Effect v4 API 和生产默认实践的技能,面向 TypeScript 应用开发。它按任务提供 Schema、服务、流、HTTP、测试等主题的参考与编码约定。
主要功能
- 01提供 Effect v4 API 使用指导
- 02按任务分类的核心模式参考
- 03基于 Schema 的模型与类型化错误
- 04服务、层和配置模式
- 05测试、流、缓存、调度与 HTTP 指引
适用场景
- 01升级使用 Effect v3 或 v4 预发布版的代码
- 02选择 Effect 服务与层的实现模式
- 03使用 Schema 建模并解码边界数据
- 04实现重试、流、缓存或 HTTP 调用
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ kitlangton/ skills --skill effect安装后在 Claude Code 中输入/effect确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/CACHING.mdCONFIG.mdHTTP_CLIENTS.mdSCHEDULING.mdSCHEMA.mdSERVICES_LAYERS.mdSTREAMS.mdTESTING.mdV4_APIS.md详细介绍
Effect
使用当前的 Effect v4 API 和此技能中的生产环境默认做法。除非任务明确要求更改,否则仍以既有项目约定为准。
源码规则
已根据 Effect 4.0.0 和上游提交
6389d9ac6 进行审查。
从 v3 或 v4 预发布版本升级时,请阅读 references/V4_APIS.md。
已安装的版本优先:预发布版本的 API 和导入路径可能有所不同。
在猜测之前,请先检查以下内容:
- 最近的
AGENTS.md和任何项目本地的 Effect 实践文档 - 项目指定的
effect包源码和版本 - 如果已安装的包无法解答问题,请查看当前上游 Effect 源码
分支选择
只阅读与任务相符的分支参考文档。
- 数据模型、模式、品牌、变体、可选键或解码器:阅读
references/SCHEMA.md。 - 服务、模块接口、层、运行时接线、错误、
Effect.fn或测试服务:阅读references/SERVICES_LAYERS.md。 - 运行时配置、环境变量、
ConfigProvider或layerConfig:阅读references/CONFIG.md。 - 重试、重复执行、轮询、退避、抖动、遵循速率限制的策略或遍历循环:阅读
references/SCHEDULING.md。 - 记忆化、按键 TTL 缓存、并发查询去重或请求批处理:阅读
references/CACHING.md。 - 流、事件源、异步可迭代对象、队列/发布订阅、分页、背压或流消费者:阅读
references/STREAMS.md。 - 发出的 HTTP 调用、Effect HttpClient、状态处理或 HTTP 速率限制:阅读
references/HTTP_CLIENTS.md。 - Effect 测试、时间、休眠、并发同步或伪实现:阅读
references/TESTING.md。
如果任务涉及多个分支,请在编辑前阅读所有匹配的文件。
核心默认做法
- 使用
Effect.gen(function* () { ... })组合工作流。 - 使用
Effect.fn("Domain.operation")定义公共服务方法和非平凡的内部服务方法。 - 仅在内部辅助函数确实不需要栈帧/跨度元数据时使用
Effect.fnUntraced。 - 如果代码库尚未统一采用其他当前服务标签风格,应用服务优先使用
Context.Service。 - 使用
Layer.effect(Service, Effect.gen(...))构建真实服务实现,并返回Service.of({ ... })。 - 使用
Schema.Struct(...)和同名interface对记录建模。 - 使用
Schema.TaggedError对带类型的 Effect 错误建模。 - 通过
Config读取运行时配置,不要在应用逻辑中直接访问process.env。 - 使用
Schedule定义重试、重复执行、轮询、节奏控制和退避策略。 - 对随时间发出多个值且需要拉取、背压、中断或转换的 Effectful 数据源,使用
Stream。 - 在 Effect 应用中发出 HTTP 请求时,若 Effect HTTP 客户端模块提供的带类型错误、层和客户端转换有用,请优先使用这些模块。
- 优先采用适配 Effect 的测试、显式层和确定性同步,而不是休眠。
- 使用
Schema.decodeUnknownEffect(...)解码未知的传输输入;对需要验证的带类型构造器输入,使用schema.makeEffect(...)。仅对可信构造使用会抛错的schema.make(...),绝不要用类型断言跳过验证。
快速选择指南
- 普通对象记录:使用
Schema.Struct(...)和同名interface。 - 标量 ID/值对象:使用带约束的品牌化 Schema。
- 内部工作流决策或状态:使用
Data.TaggedEnum<...>、Data.taggedEnum<...>()构造器和穷尽式$match。 - 可在边界间复用的带标签变体:使用
Schema.TaggedStruct(...)和同名interface。 - 跨边界带标签联合:使用
Schema.TaggedUnion(...)及其.cases、.guards和.match。 - 外部/自定义判别字段(例如
type):使用Schema.Struct({ type: Schema.tag("variant"), ... }),需要联合辅助方法时再使用Schema.toTaggedUnion("type")。 - 预期的类型化失败:使用
Schema.TaggedError。 - 未知边界负载:使用
Schema.decodeUnknownEffect(...)。 - 服务边界:使用
Context.Service<Service, Interface>()(...)、Layer.effect(...)和Service.of(...)。 - 公共或非简单的内部服务方法:使用
Effect.fn("Domain.operation")。 - 运行时配置:在各层中读取
Config配方;在测试中使用ConfigProvider覆盖。 - 事件源:使用
Stream,通过Stream.runForEach(...)消费,并在所属层中使用Effect.forkScoped派生运行。 - 基于队列的事件源:在生产者边界使用
Queue,供消费者使用Stream.fromQueue(...)。 - 广播事件源:使用
PubSub/Stream.fromPubSub(...),或使用SubscriptionRef保存最新值状态。 - 轮询工作器:使用
runPass().pipe(Effect.repeat(Schedule.spaced(...))),并在重复前处理类型化的单次运行失败。 - 重试瞬时操作:使用
Effect.retry(...)/Effect.retryOrElse(...)和有界Schedule。 - 带 TTL 和并发查找去重的键值查找缓存:当生命周期和淘汰模型合适时,优先使用
Cache.make(...)/能感知退出状态的Cache.makeWith(...)。 - 记忆化单个 Effect 结果:使用
Effect.cached(...)/Effect.cachedWithTTL(...)。 - 将 N 个键批处理为一次后端调用(仅当确实存在批处理端点时):使用
Effect.request(...)和RequestResolver。 - Effect 应用中的 HTTP 请求:优先使用 Effect
HttpClient,并对请求/响应进行 Schema 解码。 - HTTP 瞬时错误重试:使用
HttpClient.retryTransient(...)。 - 对时间敏感的测试:使用
TestClock,不要进行真实等待。 - 并发/后台测试同步:使用
Deferred、Queue、Latch、Ref或显式测试钩子。
边界规则
- 保持 HTTP 处理程序精简:解码输入、读取上下文、调用服务,并将类型化错误映射为传输响应。
- 将业务规则放在服务或领域函数中,而不是传输处理程序中。
- 在适配器边界将 HTTP 客户端、SDK、CLI 和外部集成封装为命名 Effect。
- 对不完全可信的持久化数据行,使用 Schema 或 SQL 专用辅助方法进行解码。
- 将提供方/网络调用放在权威数据库事务之外。
- 仅在当前边界能够给出真实响应时捕获或重试错误。
- 仅在操作已证明具备幂等性时重试。
- 除非边界确实有备用方案,否则让已耗尽的失败保持可见。
禁止事项
- 不要使用
as any、非空断言或未经检查的类型转换来掩盖 Effect 类型问题。 - 不要将
Schema.Class或Schema.TaggedClass用作默认的应用数据建模模式。 - 若
Schema.TaggedError适用,不要手动实现_tag错误类。 - 类型化错误恢复已足够时,不要使用原因级别的恢复。
- 不要将
Layer.mergeAll(...)或provideMerge(...)当作盲目让代码通过编译的工具。 - 不要通过
Context.Reference默认值隐藏必需的应用权限、凭据、持久化、传输或外部服务。 - 有确定性同步原语可用时,不要在测试中随意添加
Effect.sleep(...)。 - 若
effect/Cache适用,不要手动实现 Map/TTL/清理缓存或进行中请求去重。
评论
支持 Markdown