
effect-smol 修复AtomHttpApi.query的 v4 请求字段转发params/query 运行时传递与类型推断对齐解析【免费下载链接】t3code项目地址: https://gitcode.com/GitHub_Trending/t3/t3code本篇技术指南围绕 effect-smol 仓库中一次针对effect包的 patch 变更.changeset/pre/wise-ants-wave.md展开剖析AtomHttpApi.query在 v4 升级中的两个核心修复点将params/query请求字段在运行时正确转发给HttpApiClient以及对齐端点类型推断中与 v4HttpApiEndpoint一致的命名。读完本文你将理解AtomHttpApi的查询原子如何携带请求参数、如何被缓存与序列化并掌握通过回归测试与类型测试验证该行为的方法。变更背景一次面向 v4 请求字段模型的 patch 修复该 changeset 是面向effect包的 patch 级修复其变更声明原文如下FixAtomHttpApi.queryto forward v4params/queryrequest fields toHttpApiClientat runtime. Also alignAtomHttpApiendpoint type inference with v4HttpApiEndpointparams/query naming and add a regression test.它揭示了三个层面的工作运行时行为修复AtomHttpApi.query之前未能把请求的params路径参数与query查询字符串参数字段透传给底层HttpApiClient生成的端点调用函数类型层面对齐AtomHttpApi的端点类型推断改为使用与 v4HttpApiEndpoint一致的params/query命名消除 v3 遗留命名差异回归测试补全新增测试用例锁定修复后的行为防止后续回归。AtomHttpApi是什么将类型化 HTTP API 客户端接入原子响应式状态在深入修复细节前需要先理解AtomHttpApi在 effect-smol 中的定位。从 AtomHttpApi.ts 的模块文档可以看到Connects typedHttpApiclients to atoms. The service created here exposes the generated HTTP API client plus atom-based query and mutation helpers. Query atoms call endpoints and track their asynchronous result, while mutations run endpoint calls that can invalidate reactivity keys after a successful request.也就是说AtomHttpApi是类型化 HttpApi 客户端与原子响应式状态Atom之间的桥梁query 辅助函数调用端点并将异步结果封装为Atom.AsyncResult支持缓存、序列化hydration与 TTL 存活控制mutation 辅助函数执行端点调用成功后可失效invalidate指定的 reactivity keys生成的 service 本身继承了HttpApiClient.ClientGroups, never, never的形态因此可以直接获得类型化的 HTTP 客户端能力。从 index.ts 与迁移文档 v3-to-v4.mdeffect/unstable/reactivity/AtomHttpApi可以看出它被收拢在effect/unstable/reactivity这一 unstable 模块下对外暴露属于 v4 的响应式编程新体系。修复核心一query 在运行时向HttpApiClient转发 v4 请求字段self.query的请求字段组装AtomHttpApi.Service构造器内部实现了self.query其运行时实现位于 AtomHttpApi.ts。修复后的实现会显式构造一个QueryKey结构self.query (( group: string, endpoint: string, request: { readonly params?: any readonly query?: any readonly payload?: any readonly headers?: any readonly responseMode?: HttpApiEndpoint.ClientResponseMode readonly reactivityKeys?: ... readonly timeToLive?: Duration.Input | undefined readonly serializationKey?: string | undefined } ) { const key: QueryKey { group, endpoint, params: request.params, query: request.query, payload: request.payload, headers: request.headers, responseMode: request.responseMode ?? decoded-only, reactivityKeys: request.reactivityKeys, timeToLive: request.timeToLive ? Duration.fromInputUnsafe(request.timeToLive) : undefined, serializationKey: request.serializationKey } return queryFamily(key) }) as anyQueryKey接口AtomHttpApi.ts把params、query、headers、payload全部纳入查询原子的缓存键family key中——这意味着不同路径参数或查询参数会生成不同的原子实例互不串扰。从 QueryKey 到真实网络请求queryFamilyAtomHttpApi.ts是查询原子的工厂它先用self.runtime.atom(...)创建异步原子原子内部通过self.use(...)拿到生成的客户端再调用client[opts.group]opts.endpoint这里的opts正是携带params/query等字段的完整请求对象。也就是说修复后的 query 会原样把 v4 请求字段转发给HttpApiClient生成的端点调用函数在 v4 的HttpApiClient实现中这些字段会被编码为真实的 URL 路径与查询串——见 HttpApiClient.tsconst query (yield* encodeQuery(request.query)) as Recordstring, string httpRequest HttpClientRequest.appendUrlParams(httpRequest, query)回归测试如何锁定修复行为本次 changeset 特别强调add a regression test对应文件为 AtomHttpApi.test.ts。测试构造了一个带路径参数与查询参数的端点HttpApiEndpoint.get(get, /users/:id, { params: { id: Schema.FiniteFromString }, query: { page: Schema.FiniteFromString } })随后通过Client.query(group, get, { params: { id: 1 }, query: { page: 2 }, ... })发起查询并在自定义的HttpClient.makeWith中捕获实际请求断言结果assert.strictEqual(request.url, /users/1) assert.deepStrictEqual(request.urlParams, [[page, 2]])路径参数id: 1被正确渲染进 URL 路径/users/1查询参数page: 2被编码为[[page, 2]]形式的 urlParams 并追加到请求。这两条断言直接证明了query 将 v4params/query字段转发到HttpApiClient运行时的修复目标是该 changeset 的核心验收标准。修复核心二端点类型推断与 v4HttpApiEndpoint的 params/query 命名对齐除了运行时转发changeset 还对齐了类型层的命名。AtomHttpApiClient接口中query/mutation的泛型签名AtomHttpApi.ts通过HttpApiEndpoint.HttpApiEndpoint...的条件类型推断出_Params、_Query、_Payload、_Headers等类型参数并将客户端请求形状定义在HttpApiEndpoint.ClientRequest_Params, _Query, _Payload, _Headers, ResponseMode中。这里的params/query命名即取自 v4HttpApiEndpoint的类型定义保证传入Client.query(group, get, { params, query, ... })时params与query的字段会被类型系统严格校验返回的原子错误类型会通过ErrorByMode合并端点Schema错误与中间件错误HttpApiMiddleware.Error/HttpApiMiddleware.ClientError。类型层面的验证在 AtomHttpApi.tst.tststyche 类型测试中完成例如断言query与mutation原子的Failure类型包含EndpointError | MiddlewareError | MiddlewareClientError并验证response-only模式下错误类型行为与HttpApiClient一致。修复之外query 原子的缓存、序列化与 TTL 机制理解修复点的同时本次变更所在的queryFamily还完整体现了AtomHttpApi.query的进阶能力这些行为同样有测试覆盖配置项作用底层实现源码位置reactivityKeys原子挂载到指定响应式键供 mutation 成功后失效刷新self.runtime.factory.withReactivity(opts.reactivityKeys)(atom)AtomHttpApi.tsserializationKey将原子标记为可序列化hydration序列化键为AtomHttpApi:{group}:{endpoint}:{serializationKey}Atom.serializable(atom, {...})AtomHttpApi.tstimeToLive有限时长设置空闲 TTLInfinity则转为常驻keep-aliveAtom.setIdleTTL/Atom.keepAliveAtomHttpApi.ts测试 AtomHttpApi.test.ts 对这些行为给出了可验证的数值timeToLive: 1 minute时atom.idleTTL 60_000且Atom.isSerializable(atom) truetimeToLive: Infinity时keepAlive true相同serializationKey从编码输入重复创建会得到相同的序列化键且原子可被AtomRegistry挂载、经Hydration.dehydrate脱水测试中断言dehydrated[0].key与原子序列化键一致。适用前提与使用注意AtomHttpApi位于effect/unstable/reactivity属于 unstable API接口可能随 v4 迭代继续调整本次修复说明中的params/query转发语义以当前仓库 AtomHttpApi.ts 实现为准。query 的请求字段params/query/payload/headers同时参与缓存键的构造因此使用时应保证请求对象结构稳定避免因对象引用变化导致缓存命中率下降。mutation 端self.mutation通过Atom.family按{ group, endpoint, responseMode }构建成功后可用reactivityKeys触发Reactivity.mutation使相关查询原子失效AtomHttpApi.ts。该修复的意义在于v4 中params与query是分离的请求字段模型路径参数与查询字符串各司其职若AtomHttpApi.query不转发它们生成的查询原子将永远以无参数请求发起调用。回归测试正是从 URL 与 urlParams 两个维度确保该链路不再断裂。【免费下载链接】t3code项目地址: https://gitcode.com/GitHub_Trending/t3/t3code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考