@ calimero-network/mero-反应
反应约束 卡利梅罗1.0-js的28个客户端上CalimeroClient) (中文(简体) ).
一个1.0节点运行在一个经过认证的TDX集群中. 客户端验证了节点的证明,将每个请求封入节点验证的密钥,并签字人与 密码. mero-react 将一个客户端放入上下文,并在上面搭起钩子:
- 密码签入和注册;
- 由自己恢复活力的会议;
- 在应用实例上打电话、观看和直播活动;
- 组织、团队和邀请;
- (a) 节点同意页;
- 斑点和存在;
- 输入错误, 您的用户界面可以打开 .
从10x升级? 11.0是核心1.0的重写,已删除
/admin-api, (中文(简体) ),/jsonrpc, (中文(简体) ),/ws, (中文(简体) ),/sse, 美罗- 奥斯和/auth/token读取 从10.x移走 见下文.
安装
pnpm add @calimero-network/mero-react
@calimero-network/mero-js (^28.0) 随它而来,每出米罗-js出口都是再出口,所以应用只需要这个进口. 反应18或19是一种同龄依赖.
快开始
import {
MeroProvider,
ConnectButton,
useMero,
useView,
useExecute,
useSubscription,
} from '@calimero-network/mero-react';
export function Root() {
return (
// A frontend the node serves at {label}.{apps-domain}:
<MeroProvider servedByNode minReleaseVersion="2.3.109" appId={APP_ID}>
<App />
</MeroProvider>
);
}
function App() {
const { isAuthenticated } = useMero();
const items = useView<string[]>('list_items');
const { execute, failure } = useExecute();
useSubscription(undefined, (event) => {
if (event.kind === 'ItemAdded') void items.refetch();
});
if (!isAuthenticated) return <ConnectButton appName="Notes" />;
return (
<>
<ul>{items.data?.map((item) => <li key={item}>{item}</li>)}</ul>
<button onClick={() => execute('add_item', { text: 'hello' })}>Add</button>
{failure && <p role="alert">{failure.message}</p>}
</>
);
}
在别处托管的前端按名称到达 Calimero Cloud 集群, 在其节点之间失效:
<MeroProvider cluster="eu-shared-1" minReleaseVersion="2.3.109" appId={APP_ID}>
用于地方发展 merod local (三个) --dev 带模拟证明的节点,127.0.0.1:2501-2503:
<MeroProvider
nodeUrl="http://127.0.0.1:2501"
nodes={['http://127.0.0.1:2502', 'http://127.0.0.1:2503']}
allowMock
>
allowMock 接受模拟证明引用。 永远不要从任何访问者控制的东西中设置它,例如一个URL参数或一个已部署的建筑的环境.
<MeroProvider>
| Prop | 类型 | 它会做什么 |
|---|---|---|
minReleaseVersion | string | 比如说,最古老的美洛泰释放给信任 2.3.109缩写 policy: { release: { minReleaseVersion } }。 。 。 . |
policy | CloudPolicy | 完整的证明政策(简介、释放来源、, verifyQuote, (中文(简体) ), appHash) (中文(简体) ). 胜过 minReleaseVersion。 。 。 . |
allowMock | boolean | 接受模拟引用merod local, (中文(简体) ), --dev 页:1 如果 minReleaseVersion, (中文(简体) ), policy 财务报告和审定财务报表 allowMock 都不见了. |
servedByNode | boolean | 此节点服务于此页面 。 节点就是了 window.location.origin,这里有一个密码仪式 打开一个会话 约束在这个应用程序的软件包. ConnectButton 跳过节点字段. |
nodeUrl | string | 页面未保存时要使用的节点 。 没有它(没有它) cluster),提供方使用上次访问时保留的节点或集群,或等待 connectToNode 编号 : connectToCluster。 。 。 . |
nodes | string[] | 集群的其他节点,带有 nodeUrl打开 421 WRONG_NODE,或者当一个节点仍然不可用时,客户端会移动到下一个节点. |
cluster | string | 以名称命名的 Calimero 云团( 以 Calimero 为单位)eu-shared-1页:1 nodeUrl。客户端从公共节点目录(mero-js)读取集群的节点 CalimeroClient.connect他们之间失败了 目录只选择要尝试的节点: 每个节点首先在您的策略下被验证 . nodeUrl 两者均获得胜利. |
zone, (中文(简体) ), directory | string | 与 cluster: 节点先试的区域, 以及除 mero- js 以外的另一个节点目录 DEFAULT_DIRECTORY。 。 。 . |
appId | string | 默认的应用实例 . |
sessionStore | SessionStore | 会场所在. 默认是 localStorageSessionStore· ; memorySessionStore() 仅存于标签的一生. |
passkey | PasskeyProvider | WebAuthn 及时. 默认为 mero -js browserPasskey()。 。 。 . |
fetch, (中文(简体) ), retry | 路过 CalimeroClient。 。 。 . | |
client | CalimeroClient | 使用此客户端而不是构建一个,用于测试或自定义设置. |
onError | (failure) => void | 每一次失败都叫钩子或者签到报告. |
useMero()
const {
client, // CalimeroClient | null (null until a node is known, or a cluster's nodes are)
nodeUrl, // the node in use
cluster, // the cluster connected to by name, or null
isConnecting, // the node directory is being read
connectToNode, // (url) => void
connectToCluster, // (name) => void
disconnect,
session, accountId, isAuthenticated, isLoading,
signIn, // () => Promise<CalimeroSession | null>: an existing passkey
signUp, // (name) => Promise<CalimeroSession | null>: a new account and passkey
signOut, signOutEverywhere,
appId, setAppId,
passkey, servedByNode, allowMock,
failure, // the last sign-in, connection or session failure, described
reportError,
} = useMero();
会议. 1.0会话是会话符号(v2.…持续15分钟,加上一个刷新符号(rt_…),持续30天,可以使用一次.
- 客户端自己刷新到一个
401。每个等待更新的请求都会共享一个刷新,因为重新使用刷新符使会话取消。 当发布会话的节点消失后,刷新会转到集群的另一个节点(mero-js#318). - 提供者将每个新会话保存到
sessionStore,所以重新装入会话恢复. - 当拒绝刷新时,钩子就会
LoginRequired,提供者结束会话并设定failure.kind = 'login'。 。 。 . mero作为已贬值的别名client。 。 。 .
钩子
每个已读钩子返回 { data, loading, error, failure, refetch }。每个动作钩返回动作加 { loading, error, failure }。 。 。 .
error与客户端抛出的错误完全一样,所以instanceof AppError还行.failure实值describeError(error); 见 错误。 。 。 .- 动作解决
null当它失败时。 过{ throwOnError: true }把它扔出来.
App:电话、视图、事件
| 钩子 | 回返 |
|---|---|
useApp(appId?) | { appId, app, call, view, loading, error, failure, refetch }。 。 。 . call 财务报告和审定财务报表 view 被绑在应用程序上扔. |
useExecute(appId?, opts?) | { execute, call, loading, error, failure }。 。 。 . execute(method, args?, { idempotencyKey?, confirm? }) 解决方法的结果; call 解决整个问题 CallResult (单位:千美元)index, (中文(简体) ), events) (中文(简体) ). confirm: true 答题 412 CONFIRM_REQUIRED 随身钥匙(callConfirmed) (中文(简体) ). |
useView<T>(method, args?, { appId?, stale?, minIndex?, enabled? }) | { data: T, index, … }。当方法或论据发生变化时,它会再次读取. |
useSubscription(appIds?, callback, opts?) | 电话 callback 每个 AppEvent (单位:千美元){ appId, id, index, seq, kind, data }) (中文(简体) ). |
useAppAbi(appId?) | 应用程序的ABI. |
appId 默认为提供者 appId。 。 。 .
怎么样 useSubscription 行为 :
- 每个应用程序都有一个 SSE 流出一个
AbortController。卸载,或更改应用标识,中止. - 结束或失败的流会重新打开, 并且从它看到的最后一个事件返回 。 在那之前或之前的事件被跳过, 所以没有被两次交付.
from默认为'live'。通过一个日志索引从中重放(0重放整个历史).onOpen每次开出一串溪流,都叫它。 折射视图以覆盖缺口 .
应用程序
| 钩子 | 曾经是(10.x) |
|---|---|
useApps({ package?, bundle? }) | useContexts |
useCreateApp().create({ name, bundle, org?, access?, confirmMethods?, initArgs? }) | useCreateContext |
useDeleteApp().deleteApp(appId) | useDeleteContext |
useSetAppMetadata().setMetadata(appId, metadata) | useSetContextMetadata |
useUpgradeApp(appId?).upgrade({ version, … }) | useUpgradeGroup它需要密码. |
usePackages() | 无(新) |
组织和团队
| 钩子 | 曾经是(10.x) |
|---|---|
useOrg(orgId) | useNamespace |
useCreateOrg().create(name) | useCreateNamespace |
useDeleteOrg().deleteOrg(orgId) | useDeleteNamespace它需要密码. |
useSetMember().setMember(org, account, role) | useUpdateMemberRole,以及 useAddGroupMembers 在Org级别。 问道具. |
useRemoveMember().removeMember(org, account) | 无(新)。 问道具. |
useSetOrgMetadata(), (中文(简体) ), useSetMemberMetadata() | useSetGroupMetadata, (中文(简体) ), useSetMemberMetadata |
useSetCapabilities().setCapabilities(org, bits, { account?, team? }) | useSetDefaultCapabilities它需要密码. |
useTeam(org, team) | useGroupInfo |
useCreateTeam().create({ orgId, name, join?, parent? }) | useCreateGroupInNamespace |
useUpdateTeam().update(org, team, { name?, join?, parent?, metadata? }) | useSetGroupMetadata, (中文(简体) ), useReparentGroup, (中文(简体) ), useSetSubgroupVisibility |
useDeleteTeam(), (中文(简体) ), useSetTeamMember(), (中文(简体) ), useRemoveTeamMember() | useDeleteGroup, (中文(简体) ), useAddGroupMembers, (中文(简体) ), useRemoveGroupMembers设置和移除一个队员 要求密码. |
密码继位. 由于 mero-js 28 节点批准成员变化,能力,邀请,密码和API 键与呼叫者的密码:它回答 412 CONFIRM_REQUIRED 和客户端回答 提供商的 passkey (单位:千美元)browserPasskey() 因此,人看到一个密码提示。 解职的提示失败 failure.kind = 'cancelled'。 。 。 .
邀请
| 钩子 | 页:1 |
|---|---|
useCreateInvite().create({ orgId, role?, teams?, ttlSecs?, uses?, linkBase? }) | 决定: { token, link }它需要密码 链接在碎片中带有符号(#invite=…),所以它不会出现在服务器日志中. |
useRedeemInvite().redeem(token) | POST /invites/{token}/redeem不需要密码. |
useInviteRedemption({ autoRedeem? }) | 整个链接流出. 它从地址栏上读出道具,并把它取出,通过签入保存,并在被签入后赎回. status 实值 idle, (中文(简体) ), waiting-for-sign-in, (中文(简体) ), redeeming, (中文(简体) ), redeemed 或者说 failed。 。 。 . |
inviteLink(token, base?) 财务报告和审定财务报表 readInviteToken(href) 也输出.
同意页
批准只出现在节点自始至终的页面上,从不出现在一个应用中. 在应用程序前端开的会话不能批准任何东西.
const consent = useConsent();
await consent.open(upgradeConsent(appId, '1.2.0', window.location.href), {
// Show the confirmation code before leaving; the node's page shows the same one.
confirm: (started) => window.confirm(`The approval page will show the code ${started.code}. Continue?`),
}); // then navigates to the node's page
// … back on returnTo:
if (consent.returned) await consent.check(consent.returned.requestId); // confirm the hint
// or, when the page was opened in another window:
await consent.wait(started.requestId);
useConsent() 返回时 { request, open, check, wait, cancel, started, code, result, returned, … }。 。 。 . code 是确认代码( a)XXX-XXX) 正在处理中的请求的同意页:在链接旁边或输入 open是因为 confirm,这样这个人就可以检查他们降落在 他们的要求打开的页面. open 掷出 CONSENT_CODE_MISMATCH 当节点的代码与请求不符时( mero-js) confirmationCode) (中文(简体) ). 用 mero-js 构建请求 releaseConsent, (中文(简体) ), withdrawConsent 财务报告和审定财务报表 upgradeConsent。 。 。 .
集团、存在、账户
| 钩子 | 页:1 |
|---|---|
useUploadBlob({ appId? }).upload(bytes | Blob | File) | 决定: { blobId, id, size }Blobs现在属于一个应用实例. |
useBlobInfo(blobId, { appId? }), (中文(简体) ), useBlobs(appId?) | |
useBlobUrl(blobId, { appId?, mimeType? }) | { url } 是一个对象 URL。 字节来自被封存的信道, URL被取消在卸载上 . |
useDeleteBlob({ appId? }).deleteBlob(blobId) | |
useEphemeral<T>(appId, { codec?, initial?, throttleMs?, includeSelf? }) | 在场。 回返 { peers: Map<account, T>, entries, setPresence, leave, error }它每5秒发出一个心跳,然后在卸载上收回. |
useAccount() | GET /auth/me曾经 useNodeIdentity。 。 。 . |
usePasskeys() | { add, remove, label } 账户的密码。 增加和去除经核准,并配有该账户已有的钥匙; add({ passkey?, approver? }) 购买其他供应商的新钥匙和批准钥匙. |
useApiKeys() | { keys, create, revoke, refetch, … } aPI 密钥(代理、服务器). create({ label?, apps?, methods?, readOnly?, allowConfirm?, ttlSecs? }) 请求密码,需要密码会话,然后解决 { keyId, key }: 键显示一次. |
错误
mero-js 映射每次拒绝输入错误(errorFrom, mero-js #312 (英语). 元反应保持错误 error 添加 failure = describeError(error)数字 :
type Failure = {
kind: FailureKind; // see the table
message: string; // a sentence you can show as it is
retryable: boolean;
status?: number; code?: string;
appCode?: string; fields?: Record<string, unknown>; // kind 'app'
committed?: false | 'unknown'; // kind 'unavailable'
release?: string; // kind 'release-deadline'
error: unknown;
};
kind | 从 |
|---|---|
app | AppError (单位:千美元)422 APP_ERROR:应用程序本身的错误,与 appCode 名称 fields |
trap | TrapError (单位:千美元)422 TRAP(中文(简体) ) |
login | LoginRequired: 刷新被拒绝. 提供方结束会话. |
confirm 编号 : cancelled | ConfirmRequired (单位:千美元)412) (中文(简体) ) ConfirmCancelled (当事人解除了密码提示) |
wrong-node | WrongNode 编号 : 421 NOT_LEADER 失败结束后 |
unavailable | UnavailableError (单位:千美元)503 或复试后无答. 检查 committed。 。 。 . |
not-found, (中文(简体) ), forbidden, (中文(简体) ), too-large, (中文(简体) ), idempotency, (中文(简体) ), rate-limited | 404, (中文(简体) ), 403, (中文(简体) ), 413, (中文(简体) ), 409 IDEMPOTENCY_MISMATCH, (中文(简体) ), 429 |
release-deadline, (中文(简体) ), consent-stale, (中文(简体) ), operator-signature | 409 RELEASE_DEADLINE, (中文(简体) ), 409 CONSENT_STALE, (中文(简体) ), 428 OPERATOR_SIGNATURE_REQUIRED |
attestation | 封存频道或验证检查失败 |
directory | DirectoryError: 节点目录不知道集群(code: 'not-found'),列出无可用节点(empty)或无法读取 |
构成部分
<ConnectButton appName? allowSignUp? initialTab? theme? logoOnly? label? />签名,它显示"签名"并打开LoginModal签名,它显示账户, 并有一个菜单 签名和签署到任何地方.<LoginModal isOpen onClose onSignedIn? initialTab? allowSignUp? appName? theme? />。用密码签名,或创建账户,该账户要求姓名。 在节点保存的一页上,它首先询问节点URL或集群名称.
他们
传递部分 MeroTheme (单位:千美元)primary, (中文(简体) ), primaryHover, (中文(简体) ), primaryText, (中文(简体) ), background, (中文(简体) ), backgroundSecondary, (中文(简体) ), backgroundTertiary, (中文(简体) ), border, (中文(简体) ), text, (中文(简体) ), textSecondary, (中文(简体) ), error, (中文(简体) ), overlay, (中文(简体) ), radius),或设置 --mero-* 全球CSS变量:
:root {
--mero-accent: #ff4081;
--mero-accent-hover: #e91e63;
}
对话框的课是 mero-dialog-overlay, (中文(简体) ), mero-dialog-panel, (中文(简体) ), mero-dialog-title, (中文(简体) ), mero-dialog-body, (中文(简体) ), mero-dialog-field, (中文(简体) ), mero-dialog-input, (中文(简体) ), mero-dialog-button, (中文(简体) ), mero-dialog-primary, (中文(简体) ), mero-dialog-secondary 财务报告和审定财务报表 mero-dialog-link按钮的课是 mero-connect-button, (中文(简体) ), mero-dropdown 财务报告和审定财务报表 mero-dropdown-item。 。 。 .
存储
localStorageSessionStore财务报告和审定财务报表memorySessionStore(): 会话存储.getNodeUrl编号 :setNodeUrl编号 :clearNodeUrl, (中文(简体) ),getCluster编号 :setCluster编号 :clearCluster财务报告和审定财务报表getAppId编号 :setAppId编号 :clearAppId。 。 。 .clearAllStorage()清除所有上述内容.- 密钥 :
mero:session, (中文(简体) ),mero:nodeUrl, (中文(简体) ),mero:cluster, (中文(简体) ),mero:appId. 10.x 符号不读.
从10.x移走
核心1.0是一个不同的节点,而mero-js 28是一个不同的客户端,因此11.0是一个破解放出. 大多数应用端口都是机械的:
- 供养者.
- 丢弃
mode, (中文(简体) ),packageName, (中文(简体) ),packageVersion, (中文(简体) ),registryUrl, (中文(简体) ),cloudBaseUrl, (中文(简体) ),timeoutMs, (中文(简体) ),allowedNodeUrls财务报告和审定财务报表tokenStore。 。 。 . - 添加
minReleaseVersion(生产)或allowMock(单位:千美元)merod local) (中文(简体) ). - 保留
servedByNode。通过appId如果应用程序能用到一个实例.
- 丢弃
- 客户端.
useMero().mero联合国MeroJs或中继客户端)现在useMero().client联合国CalimeroClient) (中文(简体) ).mero.rpc.execute({ contextId, method, argsJson, executorPublicKey })现在client.call(appId, method, args),或client.view(…)读取.
- 词汇.
- 上下文现在是应用实例( s)
appId(三); - 命名空间现在是组织;
- 团队现在是团队;
- 执行器/节点身份现在是已签名的账户 .
- 上下文现在是应用实例( s)
- 奥特.
- 没有方向、回调或
access_token在 URL 中继续. connectToNode(url)只选择了节点。 签名为signIn()或者说signUp(name)(密码),或<ConnectButton />。 。 。 .
- 没有方向、回调或
- 错误. 打开
failure.kind,或instanceof AppError编号 :ConfirmRequired编号 :WrongNode,而不是 HTTP 状态检查.
| 10.x 电话 | 11.0 (中文(简体) ) |
|---|---|
MeroProvider mode={AppMode.X} | MeroProvider minReleaseVersion=… | allowMock (没有模式, 没有权限范围) |
useMero().mero | useMero().client (单位:千美元)mero 保留为已贬值的别名) |
useMero().contextId 编号 : contextIdentity 编号 : applicationId | useMero().appId 编号 : accountId / 无 |
useMero().isOnline | 无: 客户端自己重试失败 |
connectToNode(url) + 重定向登录 | connectToNode(url) + 键 signIn() 编号 : signUp(name) |
connectWithAccount, (中文(简体) ), isDelegated, (中文(简体) ), can, (中文(简体) ), admin | 无(无转发、无授权账户) |
useExecute(contextId, executorId).execute(m, p) | useExecute(appId).execute(m, args, { confirm?, idempotencyKey? }) |
| 无 | useView(method, args), (中文(简体) ), useApp(appId) |
useSubscription(contextIds, cb) 编号 : { contextIds, groupIds } | useSubscription(appIds, cb, { from?, onOpen? }) |
useContexts, (中文(简体) ), useApplicationContexts, (中文(简体) ), useNamespacesForApplication | useApps({ package? }) |
useCreateContext, (中文(简体) ), useCreatePrivateContext | useCreateApp (单位:千美元)access 私人应用程序) |
useDeleteContext, (中文(简体) ), useSetContextMetadata | useDeleteApp, (中文(简体) ), useSetAppMetadata |
useNamespace, (中文(简体) ), useNamespaces, (中文(简体) ), useCreateNamespace, (中文(简体) ), useDeleteNamespace | useOrg, (中文(简体) ), useAccount (英文), useCreateOrg, (中文(简体) ), useDeleteOrg |
useGroupInfo, (中文(简体) ), useNamespaceGroups, (中文(简体) ), useSubgroups, (中文(简体) ), useContextGroup | useTeam (队伍列于 useOrg(中文(简体) ) |
useCreateGroupInNamespace, (中文(简体) ), useDeleteGroup | useCreateTeam, (中文(简体) ), useDeleteTeam |
useAddGroupMembers, (中文(简体) ), useRemoveGroupMembers, (中文(简体) ), useGroupMembers | useSetTeamMember, (中文(简体) ), useRemoveTeamMember, (中文(简体) ), useTeam |
useUpdateMemberRole, (中文(简体) ), useGroupCapabilities, (中文(简体) ), useSetDefaultCapabilities | useSetMember, (中文(简体) ), useOrg, (中文(简体) ), useSetCapabilities |
useSetGroupMetadata, (中文(简体) ), useGroupMetadata, (中文(简体) ), useMemberMetadata | useSetOrgMetadata 编号 : useUpdateTeam, (中文(简体) ), useOrg 编号 : useTeam |
useReparentGroup, (中文(简体) ), useSetSubgroupVisibility | useUpdateTeam({ parent, join }) |
useCreateNamespaceInvitation, (中文(简体) ), useGroupInvitations | useCreateInvite |
useRedeemInvitation, (中文(简体) ), useJoinNamespace, (中文(简体) ), useJoinGroup, (中文(简体) ), useJoinContext | useRedeemInvite |
useInviteRedemption, (中文(简体) ), useJoinInvitation | useInviteRedemption (无中继或同步步骤) |
useUpgradeGroup, (中文(简体) ), useInstallFromRegistry | useUpgradeApp,或 useConsent + 键 upgradeConsent 从附件前端 |
useGroupUpgradeStatus, (中文(简体) ), useRetryGroupUpgrade | 美罗 client.upgradeRun 编号 : retryUpgradeRun (org升级运行) |
useUploadBlob, (中文(简体) ), useBlobInfo, (中文(简体) ), useBlobUrl | 相同名称, 现在每个应用程序( S){ appId }(中文(简体) ) |
useEphemeral(contextId, opts) | useEphemeral(appId, opts): 按账户键的对等点 |
useNodeIdentity | useAccount |
classifyError(err) 编号 : ClassifiedError | describeError(err) 编号 : Failure |
getPermissionsForMode, (中文(简体) ), AppMode, (中文(简体) ), ConnectionType | 删除( 无权限范围) |
localStorageTokenStore, (中文(简体) ), get/setContextId, (中文(简体) ), get/setApplicationId, (中文(简体) ), get/setContextIdentity | localStorageSessionStore, (中文(简体) ), get/setAppId |
无替换删除 (v1 或仅桌面) :
- 管理员- API 钩子 :
useSyncGroup, (中文(简体) ),useResyncContext, (中文(简体) ),useJoinSubgroupInheritance, (中文(简体) ),useDetachContextFromGroup, (中文(简体) ),useSetTeeAdmissionPolicy, (中文(简体) ),useContextDiscovery· ; - 迁移钩和组件 :
useMigrationStatus, (中文(简体) ),useMigrationEvents, (中文(简体) ),useMyAuthoredMigration, (中文(简体) ),MigrationPendingBanner, (中文(简体) ),MigrationAdminPanel· ; - 版本钩子 :
useAppVersion, (中文(简体) ),useLatestVersion, (中文(简体) ),useGroupAppVersion· ; - 授权/中继/账户注册层:
useAccountEnrolment, (中文(简体) ),useDelegatedBootstrap, (中文(简体) ),ConnectButtonAccount, (中文(简体) ),AccountSignInPanel还有接力,joinWithNode财务报告和审定财务报表bootstrapFromInvitation再出口; - 邀请 UI :
InvitationGate, (中文(简体) ),InvitationDialog, (中文(简体) ),JoinSyncBanner, (中文(简体) ),useJoinSync· ; - 本地节点发现 :
discoverLocalNodes· ; - 桌面 (Tauri) :
isDesktopWindow。 。 。 .
许可证
麻省理工学院