@ 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()。 。 。 .