@client-compose/client

中文文档
0.16.0发布于 2026/10/30MITTypeScriptES Module构建来源已验证近 30 天下载 2945

框架不可知客户编制客户:岛屿登记、筛选请求和提供规划.

中文使用文档
文档目录8 节
  1. 使用量
  2. 流线
  3. 行动
  4. 有页的岛屿
  5. 字符串
  6. 测试
  7. 通过您的服务器
  8. 链接

@ client- compose/ 客户端

框架不可知客户端 客户端编译数字 : 由客户拥有的岛屿组成的服务器屏幕协议.

等级 : 核心项目 议定书: 页:1 任何联署材料运行时间 fetch (浏览器,反应原生,节点20+)

npm install @client-compose/client

使用反应还是反应原生? 使用 @client-compose/react, (中文(简体) ), 以此为基础.

使用量

IslandRegistry<R> 将岛屿类型和版本映射给渲染器. R 无论你的UI做的是什么 (一个DOM节点,一个HTML的字符串,一个框架元素),因此这个核心与任何UI层一起工作.

import { buildRequest, fetchScreen, IslandRegistry, plan } from "@client-compose/client";
import { ProfileHeaderV2 } from "./islands.generated"; // from @client-compose/codegen

const registry = new IslandRegistry<HTMLElement>()
  .register(ProfileHeaderV2, (props) => renderProfileHeader(props));

const request = buildRequest(registry, "profile", { platform: "web", appVersion: "1.4.0" }, { userId });
const response = await fetchScreen("https://api.example.com/compose", request, {
  headers: { Authorization: `Bearer ${token}` },
});

const islands = plan(registry, response, {
  onSkipped: (entry, reason) => console.warn("skipped island", entry.key, reason),
});
container.replaceChildren(...islands.map((island) => island.render()));
  • buildRequest 发送岛类型和版本 这个客户端可以渲染, 所以作曲家 永远也回不来.
  • plan 返回可转换岛屿。 错误的岛屿被省略,除非您通过 onError; 类型、版本或状态不明的岛屿被跳过和报告.
  • registry.declare(...) 应用程序在服务器上等其它地方制作的名字: 注册人无法制作它们,但动作说应用程序可以绘制它们,并更改它们 实体对其适用(第5.3节).
  • fetchScreen 读取屏幕的流到它的末端,然后返回整个. 它会扔 ScreenFetchError (与 status 财务报告和审定财务报表 body非-2xx回复,并接受习惯 fetch 作为它的第四个论点.

流线

屏幕作为溪流而来(第4.6段):它的头,任何岛屿还没有准备好 pending,则 每个作为作曲家的人都会决定. openScreen 头一进去就解决了,这样你就可以 显示屏幕并填入:

const stream = await openScreen(baseUrl, request, init);
let screen = stream.head;
show(plan(registry, screen)); // pending islands are their placeholders, or left out
for await (const island of stream.islands) {
  screen = withIsland(screen, island);
  show(plan(registry, screen));
}
  • 为岛屿登记占地者 registry.registerPlaceholder(Descriptor, () => …)数字 : plan 在岛上待决时展示 没有它,这个岛就被排除在外,直到它到达.
  • 一条溪流从不带的岛屿(断了的连接) 是一个错误, incomplete, (中文(简体) ), 可重试.
  • collectScreen(stream) 读取其余部分并返回整个屏幕.
  • 身体读来读来读去 fetch 给一个可读流(浏览器、节点、德诺、邦、, 财务报告和审定财务报表 expo/fetch (原始内容存档于2018-09-31). React Industrial. 反应原生的内置 fetch 没有,所以有屏幕 马上就到.

行动

import { ActionFetchError, callAction } from "@client-compose/client";
import { FollowUserV1 } from "./actions.generated"; // from @client-compose/codegen

const res = await callAction("https://api.example.com/compose", FollowUserV1, { userId }, {
  client: { platform: "web", appVersion: "1.4.0" },
  islands: registry.capabilities(), // updates come at versions the app can render
  init: { headers: { Authorization: `Bearer ${token}` } },
});
if (res.status === "ok") showFollowers(res.result.followers); // and apply res.effects (spec §5.3)
else if (res.error.code === "blocked") showBlocked();
else showGenericError(); // codes added after this app was built
  • 宣布的错误是结果(status: "error"每个动作键入。 其他的,比如说 invalid_input, (中文(简体) ), unauthenticated 或者说 action_failed掷出 ActionFetchError 与 status 财务报告和审定财务报表 code。 。 。 .
  • 每一次通话都会发出一个新的一能键. 过 idempotencyKey {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}你自己来重试同样的意图.

在运行时不会验证道具; 生成类型 @client-compose/codegen 让他们留在 与作曲家同步.

有页的岛屿

岛屿入口载着 next 岛上的网页更多(第4.5节). fetchIsland(baseUrl, buildIslandRequest(screen, params, entry, client, entry.next)) 获取 下一页: 岛上再次进入, 加上那页的道具和它自己的 next。没有光标,它 重新解决该岛的第一页。 反应束缚 usePages 这样做是为了你.

字符串

每个词都来自作曲家(spec §4.7). 由具有下列特征的描述者对岛屿进行登记: 宣布弦,它的制造者道具有它们作为 t,在屏幕的语言,计数 字符串按其复数规则选择其词:

registry.register(ArticleListV1, (props) => `${props.t.heading}: ${props.t.articleCount({ count: props.total })}`);

应用字符串来自 POST {base}/strings数字 :

const response = await fetchStrings(baseUrl, client);
const t = appStrings(AppStrings, response); // t.retry, t.uploaded({ count, total })

发送该人的语言作为 client.locale· ; preferredLocale 从设备的标签中选择,或者 接受语气标题( C)preferredLocale("pl-PL,pl;q=0.9") 实值 "pl-PL")和作曲家 用它最近的语言回答. formatString(template, values, plurals) 财务报告和审定财务报表 pluralCategory(plurals, count) 还有其他事 在测试中,假作曲家回答 strings: () => stringsResponse("en", { … }), (中文(简体) ), 财务报告和审定财务报表 island(key, Descriptor, props, { strings }) 给一个岛屿 其弦. catalogStrings(catalog) 读取目录文件( codegen's) catalog作曲家会寄给它 用来测试 真实词 : t(Descriptor), (中文(简体) ), app(AppStrings), (中文(简体) ), island(…) 与它的弦,和 stringsResponse()。 。 。 .

测试

@client-compose/client/testing 是一个假作曲家 测试, 没有自己的测试框架. createFakeGateway 回答处理器的屏幕和动作请求并记录它们;通过它 fetch 给客户的 构建响应 island, (中文(简体) ), islandError, (中文(简体) ), screen, (中文(简体) ), screenError, (中文(简体) ), actionOk, (中文(简体) ), actionError 财务报告和审定财务报表 actionFailure,按生成的描述符键。 A 类 screen 实值 为了控制每个岛屿的到来,请回答 streamedScreen(id, [island(…), pending(key, Descriptor)]),然后调用它的 send(entry), (中文(简体) ), end(), (中文(简体) ), 或者说 cut() 连接中断.

import { actionError, createFakeGateway } from "@client-compose/client/testing";

const gateway = createFakeGateway({
  actions: { follow: () => actionError(FollowUserV1, { code: "blocked" }) },
});
const res = await callAction(baseUrl, FollowUserV1, { userId }, { client, islands: {}, fetch: gateway.fetch });
assert.equal(gateway.actionRequests()[0].input.userId, userId);

对于被称为全球的代码 fetch 自己,像一个完整的应用 在测试, installFakeGateway(handlers) 把假作曲者放在原位; 打电话 restore() 后来.

对于反应, @client-compose/react/testing 添加围绕它构建的提供者配置 .

通过您的服务器

@client-compose/client/proxy 将浏览器的屏幕、岛屿和行动请求传递给作曲家 通过您的服务器, 它可以添加浏览器不能持有的东西, 例如保存在一个 httply Cookie. (原始内容存档于2018-09-27). createComposerProxy({ baseUrl, client, headers, onActionResponse }) 检查每个 请求(任何人都可以用任何东西调用服务器端点),设置客户端上下文和信头, 并返回作曲者的失败作为数据. @client-compose/react是因为 viaProxy 是浏览器 半个.

字符串也会通过您的服务器 : proxy.loadStrings()。 。 。 .

版本与发布记录

@client-compose/client 共发布 18 个版本,首次发布于 2026/10/19;过去 12 个月发布了 18 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.16.0latest2026/10/3011 天前
0.15.02026/10/3011 天前
0.14.02026/10/2911 天前
0.13.02026/10/2911 天前
0.12.02026/10/2911 天前
0.11.02026/10/2912 天前

关于 @client-compose/client 的常见问题

@client-compose/client 是什么?

框架不可知客户编制客户:岛屿登记、筛选请求和提供规划.

如何安装 @client-compose/client?

在项目目录运行 npm install @client-compose/client,或使用 pnpm add / yarn add / bun add。

@client-compose/client 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@client-compose/client 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@client-compose/client 可以商用吗?

@client-compose/client 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@client-compose/client 的下载量有多少?

根据 npm 官方下载统计,@client-compose/client 在 2026/10/10 – 2026/11/08 这 30 天内被下载 2,945 次,日均约 98 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@client-compose/client 还在维护吗?

最新版本 0.16.0 发布于 2026/10/30(11 天前);至今共发布 18 个版本,其中过去 12 个月发布了 18 个;首次发布于 2026/10/19。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。