v0.18:Scalar、类型化文件下载、过滤感知的 Collection
v0.18 聚焦于三件事:对随请求上下文变化的值进行更丰富的数据建模、更简单的类型化下载,以及更贴近真实 API 过滤条件的集合匹配。
新特性:
- Scalar schema - 随视角(lens)变化的实体字段(例如特定投资组合的数值),且永不修改底层实体
- RestEndpoint
content属性 - 只用一个属性即可实现类型化文件下载、文本响应和流式传输 - resource()
nonFilterArgumentKeys- 排序/分页参数不再把你的 Collection 拆散
其他改进:
- 二进制 Content-Type 自动检测 - 图片、PDF 及其他二进制响应无需任何配置即可自动处理(#3868)
- Collection 扩展方法的 body 类型与 HTTP 方法语义一致 - PATCH 扩展方法(
.move、.remove)接受部分 body;独立的 RestEndpoint 会从 Collection 的实体 schema 推导出类型化的 body(#3910) - 从
@data-client/endpoint和@data-client/rest导出CollectionOptions,用于类型化地构造 Collection(#3904)
import { Collection, Entity, RestEndpoint, Scalar } from '@data-client/rest'; export class Company extends Entity { id = ''; name = ''; price = 0; pct_equity = 0; shares = 0; } const PortfolioScalar = new Scalar({ lens: args => args[0]?.portfolio, key: 'portfolio', entity: Company, }); Company.schema = { pct_equity: PortfolioScalar, shares: PortfolioScalar, }; export const getCompanies = new RestEndpoint({ path: '/companies', searchParams: {} as { portfolio: string }, // `portfolio` is a lens, not a filter — the returned Company list is the same // regardless of lens. Dropping it from `argsKey` collapses every portfolio to // one Collection pk, so `Collection.queryKey()` finds the list on every // switch and `useSuspense` reuses it without refetching. schema: new Collection([Company], { argsKey: () => ({}) }), }); export const getPortfolioColumns = new RestEndpoint({ path: '/companies/columns', searchParams: {} as { portfolio: string }, schema: new Collection([PortfolioScalar], { argsKey: ({ portfolio }: { portfolio: string }) => ({ portfolio }), }), });
这个示例展示了同一批 Company 实体通过不同的投资组合视角进行渲染。稳定的 Entity 字段会被复用,而随视角变化的值则从独立的 Scalar 单元格中选取。
- Schema.denormalize() 接收 delegate -
denormalize(input, args, unvisit)→denormalize(input, delegate)。仅影响自定义 Schema 实现。 - Schema.normalize() 接收 delegate -
normalize(input, parent, key, args, visit, delegate)→normalize(input, parent, key, delegate)。仅影响自定义 Schema 实现。
**在使用 AI 智能体?**安装迁移 skill——它会运行 codemod,为依赖参数的 schema 注册
argsKey,并处理 codemod 无法覆盖的情况(类字段、动态方法赋值、SFC <script> 块、自定义辅助函数):
- Skills
- OpenSkills
- Claude Code
npx skills add reactive/data-client --skill data-client-v0.18-migration
npx openskills install reactive/data-client/.agents/skills/data-client-v0.18-migration
claude plugin marketplace add reactive/data-client
claude plugin install migrations@data-client
否则,直接运行 codemod——它覆盖了常见情况:
npx jscodeshift -t https://dataclient.io/codemods/v0.18.js --extensions=ts,tsx,js,jsx src/
