@collective-intelligence/extensions-sdk-frontend-react
集体所作反应贡献的公开、东道方中立合同 情报工作室或Dashboard.
React and React DOM 是主机提供的同位素. 可选
@collective-intelligence/ui-react 导入时需要对等点
/workflow 或者说 /ui-react 子路径; 仅声明消费者不需要它.
effect (单位:千美元)^4.1.0)是需要的对等点:应用程序安装一个副本 effect, (中文(简体) ),
而软件包的构建保持了外部。 这个 /effect 切入点输出
StudioApi 服务;见 关于效果的 Studio API。
还出口 fromEffect, (中文(简体) ), EffectRuntimeProvider, (中文(简体) ), useEffectRuntime 财务报告和审定财务报表
QueryCache,在 Studio 部件中写入的部分;见
在工作室部件中写入他们需要
所需经费 xstate ,由工作室和 Dashboard 主机提供.
import { declareFrontendCatalogContribution } from "@collective-intelligence/extensions-sdk-frontend"
import { declareStudioComponent } from "@collective-intelligence/extensions-sdk-frontend-react/studio"
import { customerPageProps } from "./schemas"
const sourceRef = "com.acme.crm.studio.customer-view"
export const studioCatalog = declareFrontendCatalogContribution({
fqn: sourceRef,
host: "studio",
load: () => import("./studio-catalog")
})
export const customerPage = declareStudioComponent({
definition: {
category: "page",
propsSchema: customerPageProps,
sourceRef
},
manifest: {
fqn: "com.acme.crm.studio.customer-page",
version: "1.0.0"
},
presentation: { displayName: "Customer" }
})
声明是数据:不向 Studio 或 Dashboard 注册
不拥有模块发送、主机解析或错误边界渲染。 目录
主机贡献来自React-free前端SDK,可以传递到
declarePackage({ hostedContributions: [...] })他们懒惰 load 函数
永远不要输入序列包清单。 此反应包有意
不暴露已退休的叶子 declareStudioView 或者说
declareDashboardWorkflowField 帮手.
sourceRef 每个工作室组件都需要切出叶子并保留在
串行包清单。 它能识别同一个包的主机
工作室贡献; 它不是一个源路由, 也不是另一个运行时间 URL .
前端运行时间
这个 frontend 入口提供了共享的 React 执行边界
报表 @collective-intelligence/extensions-sdk-frontend数字 :
import {
createHostedDiagnostic,
HostedExtensionRender,
loadDeclarationModule
} from "@collective-intelligence/extensions-sdk-frontend-react/frontend"
;<HostedExtensionRender
declaration={declaration}
componentProps={{ customerId: "customer-1" }}
load={() => loadDeclarationModule(declaration)}
/>
前端入口拥有模块加载, React 组件验证,以及
错误的边界诊断。 它还出口 createHostedDiagnostic 编辑
HostedDiagnostic, (中文(简体) ), HostedDiagnosticPhase,以及 SourceMapLocation 类型
在提供的渲染边界外报告故障的主机 。 东道主
应用程序仍然拥有目录激活、路由和产品专用
倒计时 UI.
将主机树包入 HostedExtensionFailureProvider 替换平原
与主机自己的设计系统 UI 的失败消息 。 内容 render 回调
接收 HostedDiagnostic。装入失败也被登录
console.error 及其原始原因; React logs 生成失败.
HostedExtensionRender 在道具或召回时保留挂载组件
身份变化,保留本地编辑和焦点. 装入时重新启动
声明对象或 implementationRole 更改; 主机应保留声明
稳定,直到捐款发生变化。 使用最新的负载故障
onDiagnostic 调用.
工作流量UI
这个 workflow 切入点提供主机中立的工作流程字段和节点
渲染器、目录活化器和查询辅助器:
import {
WorkflowFieldResolver,
activateWorkflowCatalog,
workflowFieldOptions
} from "@collective-intelligence/extensions-sdk-frontend-react/workflow"
字段绑定使用 inputBinding 节点 inputs 财务报告和审定财务报表 parameter 节点
config。导出的读取和补丁帮助保存了兄弟姐妹的值并存储
字段在元数据中显示相同条形绑定键下的标签。 存储
{mode: "fixed"} 信封和编译的文字在每条路径上都解开
当字段渲染器或字段时 visibleWhen 规则是具有约束力的;
表达式值通过不变。 可见度 equals 比较JSON
结构,以及 in 匹配一个平面值或多值的任何成员
字段. CatalogNodeDetailsEditor 以升起方式使段落和字段
order (默认0,领带保持声明令). resource_selector 财务报告和审定财务报表
credential_selector 字段仅解为部件后退的
选择远程选项, 显示已声明的字段 placeholder。 。 。 .
WorkflowFieldFrame 财务报告和审定财务报表 ExpressionSlot 接受可选 help 文本,在字段标签下显示。 自定义固定和表达式控件应转发渲染道具 describedBy 他们的投入 aria-describedby,保留任何现有的描述标识。 内置表达式编辑器将这种上下文帮助与验证描述相结合. 只读字段将保存的固定模式或表达模式显示为文本 .
打开表达式建议保留表达式输入或文本领域的焦点, 因此,打字在作者值中继续。 建议查询仍明确 可用于过滤和插入可用值.
主机通过提供远程工作流程域选项
configureWorkflowFieldOptionsProviderSDK把适配器放在外面
公用软件包,这样可以使用不同的后端相同的工作流程 UI
客户端和主机应用程序.
主机可以提供 context.chart.presentation 带有 icon 反应组件
(接受任择) className)和a 数据 tone CSS类字符串. 使用节点
类型中的语义图标及其类别在目录和
画布. CatalogNodeChartBlock 对卡片和图标应用提供的语气
徽章,在制作者的遗产之前 accent。默认图表和内置
图表覆盖此组件的授权共享此行为 。 无
演示文稿,独立消费者保留以实物为基础的图标和口音.
主机拥有身份解析度; 公共 SDK 不导入主机目录
或私人列报登记册.
主机给 context.template.label 财务报告和审定财务报表 context.template.description 改为
主机渲染器为 WorkflowLocalizedText数字 : { kind: "literal", text } 或者说
{ kind: "translation", default }使用另一个目录运输的东道主
形状在构建上下文之前转换它. CatalogNodeChartBlock 显示
context.chart.title 财务报告和审定财务报表 context.chart.description 当主摆放的时候,
和模板文本.
图表显示每个已申报的输入和输出及其端口名称、方向、, 连接限制,并允许对等限制 。 港口目标为20像素宽; 该卡会增长, 以保持密集的端口列表, 并在上下文中添加控件 .
工作室 API
这个 studio-api 入口是后端操作的生成客户端
表示主机 Studio 部件将使用。 后端标记每个这样的
操作 widget-public OpenAPI 标签 。 标签选择客户端
生成;它不是一个授权边界。 每个请求都与
登录用户自己的权限, 后端也像其他用户一样授权
请求。 切入点导出 SDK 函数, 其类型, TanStack 查询
选项、变异选项和查询密钥,以及 client 举个例子 工作室
主机将客户端绑定在其认证的传输上; 部件不配置
证书。 每一个部件共享一个束缚 client,所以主机锁定它:
client.setConfig 和每个 client.interceptors 换发. 设置信头
和其他请求选项,每个呼叫.
工作室视图上下文
工作室主机给出每个位置的视图和部件组件 a context 道具
在它配置的道具旁边。 这个 /studio 输入点将其打入
StudioViewComponentProps数字 :
type StudioViewContext = Readonly<{
appId: string
appSlug: string
organizationId: string
pageId: string
publishedRevisionId: string
viewId: string
}>
type StudioViewComponentProps = Readonly<{
context: StudioViewContext | null
}>
当应用程序安装时, Studio 生成视图、页面和修订 ID 或
,所以声明不能命名它们 context。 。 。 .
context 实值 null 当视图没有被公布的位置时:在建构者中
预览,没有组织,或者在app有已发布修订版之前.
在此情况下隐藏或禁用部件的 API 呼叫 .
studioViewScope(context) 返回时 headers 财务报告和审定财务报表 path 选项
视图数据操作. studioPublishedViewScope(context) 返回时
headers 财务报告和审定财务报表 query 已公布视图上的操作选项,例如
studioWorkflowRunsList数字 :
import type {
StudioViewComponentProps,
StudioViewContext
} from "@collective-intelligence/extensions-sdk-frontend-react/studio"
import { studioViewScope } from "@collective-intelligence/extensions-sdk-frontend-react/studio"
import { studioViewDataSearchOptions } from "@collective-intelligence/extensions-sdk-frontend-react/studio-api"
import { useQuery } from "@tanstack/react-query"
const CustomerRows = ({ context }: { context: StudioViewContext }) => {
const rows = useQuery(
studioViewDataSearchOptions({
...studioViewScope(context),
body: { limit: 10 }
})
)
return <output>{rows.status}</output>
}
export const CustomerWidget = ({ context }: StudioViewComponentProps) =>
context === null ? null : <CustomerRows context={context} />
src/studio-api/ 产生并致力于。 后端更改为 a
标记操作, 运行 bun run --filter @repo/backend api:openapi,则
bun run api:codegen:studio-api 本包中。 CI 运行
api:codegen:studio-api:check 并且当责任委托人僵持时失败.
新的行动也需要在 StudioApi; 测试失败直到它
有一个.
关于效果的 Studio API
这个 /effect 切入点输出 StudioApi 服务。 每条路有一条路
联 合 国 studio-api 客户端,名称相同,请求选项和
成功类型. StudioApi 调用共享 studio-api 客户端: 它导入
客户端通过 ./studio-api,所以一个工作室部件给客户端打电话说
工作室主机绑定。 工作室扩展放行捆绑 /effect 保留
/studio-api 外部; 发布构建需要一个 ci 这个CLI版本
捆绑 SDK ./effect 子路径(参见 CLI changelog). 只有工作室
主机提供 /studio-api。一个 Dashboard 发布它自己的副本
客户端,没有Host绑定副本.
/effect 进口 /studio-api 以名为相. 在一个工作室
扩展,工作室主机提供该模块. 如果 /studio-api 会 议 日 程 和 议 程
主机不出口其中一项业务, /effect 不装入,也不装入
对于一个不称为操作的部件。 使用 /effect 只有一个
工作室 这个SDK版本的宿主 或保存每个版本的后期版本
操作.
import type { StudioViewContext } from "@collective-intelligence/extensions-sdk-frontend-react/studio"
import {
layerStudioApi,
StudioApi
} from "@collective-intelligence/extensions-sdk-frontend-react/effect"
import { studioPublishedViewScope } from "@collective-intelligence/extensions-sdk-frontend-react/studio"
import * as Effect from "effect/Effect"
const runCount = (context: StudioViewContext) =>
Effect.gen(function* () {
const api = yield* StudioApi
const page = yield* api.studioWorkflowRunsList(
studioPublishedViewScope(context)
)
return page.data.length
}).pipe(
Effect.catchTag("StudioApiError", (error) => Effect.fail(error.status)),
Effect.provide(layerStudioApi())
)
- 错误答案失败
StudioApiError它握着status编辑body客户端读取(JSON,其他文本)。 客户端不检查body,并且生成出错映射以外的状态,例如 a 的 502 代理,持有任何尸体。 这么说吧body实值unknown: 用Schema来解码 在使用前使用. - 未到达后端的请求, 或未知答案
可读, 失败
StudioApiTransportError,它持有cause。 。 。 . - 错误的输入,例如JSON无法写的正文,是一个
TypeError败坏. 请求没有离开. - 纤维中断会中止请求 .
- 服务
client, (中文(简体) ),fetch, (中文(简体) ),baseUrl, (中文(简体) ),signal, (中文(简体) ),responseStyle财务报告和审定财务报表throwOnError。设置标题和其他请求选项.
layerStudioApi({ baseUrl }) 将每个请求发送给 baseUrl工作室部件
给定没有基础 URL: 主机将客户端绑定到其后端并拒绝其他
URLs (英语). 没有绑定客户端的主机,例如测试或预览,给出
其后端的 URL。 URL是部署配置,所以
layerStudioApiConfig({ baseUrl: Config.String("STUDIO_API_BASE_URL") })
用效果读出来 Config。 。 。 .
在工作室部件中写入
A Studio Widget 遵循一个脱开的应用程序的写入常规,以及
ci-solution/effect-writes 财务报告和审定财务报表 ci-solution/effect-actors 适用于
它: 写作在 fromEffect X 状态演员, 视图读取 useQuery, (中文(简体) ),
之后,演员刷新读取 QueryCache。 。 。 .
/effect 出口这些部件:
EffectRuntimeProvider给其树一个效果运行时间QueryCache超过最近的QueryClient,这是QueryClient联 合 国 工作室主机。 主机挂载没有效果运行时间 。 每个部件挂载EffectRuntimeProvider根部:每个部件的捆绑都有自己的 存档副本/effect,因此它看不到另一捆的提供者.useEffectRuntime()给运行时间。 风景传到机器上 开始,输入.fromEffect(run)使 X 状态演员逻辑运行效果run打开input.runtime演员的一站打断了纤维;在一站之后,不 运行的结果得到演员, 也在一个反应严格模式重载.QueryCache已经fetch, (中文(简体) ),invalidate, (中文(简体) ),cancel, (中文(简体) ),setData, (中文(简体) ),update财务报告和审定财务报表remove。 。 。 .invalidate, (中文(简体) ),cancel, (中文(简体) ),update财务报告和审定财务报表remove适用于密钥和 它下面的每个键.fetch运行一次查询, 不重试, 失败 与StudioApiError或者说StudioApiTransportError; 另一个失败是 败坏. 取消密钥会中断查询; 等待fetch接下来 返回缓存值,或当密钥没有值时中断.cancel取消运行中的抓取, 因此它们不写值; 它保留 缓存值并开始不获取 。 一个乐观的写作电话cancel,则update,运行写作,和打电话invalidate当书写安定的时候。 这个 主机和所有部件共享一个QueryClient,所以从每个键开始 软件包名称.makeTestQueryCache(options?)给机器测试QueryCache一个以上 真实QueryClient其所属单位:layer页:1ManagedRuntime.make, (中文(简体) ),queryClient以播种,而坚持calls,一个{ member, queryKey }每一次通话.options.overrides替换 只有它所命名的成员;options.seed持有第一个条目. 用它来测试, 从来没有用双人制成QueryCache.of({ ... }),哪个 每次断开QueryCache得到一个成员。 它不增加依赖,a 不导入的部件包并不包含它 .
import type { EffectRunner } from "@collective-intelligence/extensions-sdk-frontend-react/effect"
import type { StudioViewContext } from "@collective-intelligence/extensions-sdk-frontend-react/studio"
import {
EffectRuntimeProvider,
fromEffect,
layerStudioApi,
QueryCache,
StudioApi
} from "@collective-intelligence/extensions-sdk-frontend-react/effect"
import { studioViewScope } from "@collective-intelligence/extensions-sdk-frontend-react/studio"
import * as Effect from "effect/Effect"
import { setup } from "xstate"
const customersKey = ["com.acme.crm", "customers"] as const
type RenameInput = Readonly<{
context: StudioViewContext
instanceId: string
name: string
runtime: EffectRunner<QueryCache>
}>
export const renameMachine = setup({
actors: {
rename: fromEffect((input: RenameInput) =>
Effect.gen(function* () {
const api = yield* StudioApi
const scope = studioViewScope(input.context)
yield* api.studioViewDataUpdateItem({
...scope,
body: { name: input.name },
path: { ...scope.path, instanceId: input.instanceId }
})
const cache = yield* QueryCache
yield* cache.invalidate(customersKey)
}).pipe(Effect.provide(layerStudioApi()))
)
}
}).createMachine({/* states that invoke "rename" with the input above */})
// The widget root: the runtime is over the QueryClient of the Studio Host.
export const CustomersWidget = (props: CustomersViewProps) => (
<EffectRuntimeProvider>
<CustomersView {...props} />
</EffectRuntimeProvider>
)
xstate (单位:千美元)^5.33.3)是需要的对等点。 工作室和Dashboard主机提供
他们唯一的副本 xstate,则 ci CLI 保留 xstate 两者均为外部
Hosts的艺术品, 所以一个部件包 携带没有副本 X State。 第一个
提供主机 xstate 第一次ci-app发布后
@collective-intelligence/[email protected]与保留它的CLI一起
外部: 使用 CLI 或稍后运行在主机上的发布
科普发布或后一. 使用部件 @xstate/react 把它捆起来;
它导入主机副本 react 财务报告和审定财务报表 xstate。 。 。 .
仅从 xstate: 主机提供一个名称和一个
释放一个子路径, 如 xstate/actors,这是第二本
X州报. 主机不检查 xstate 部件版本: 构建
反对: xstate 5号是东道主的船.
工作区大楼
这个软件包需要构建 @collective-intelligence/ui-react 声明
汇编自己的宣言。 从寄存器根运行
bunx turbo run build --filter=@collective-intelligence/extensions-sdk-frontend-react
按顺序构建此软件包及其依赖关系。 工作空间的发展
依赖 ui-react 用于构建订单的用品;它仍然是可选的
用于已发布的软件包的消费者的对等点.
主机模块参考文献可能提供a load 并列调用 module 财务报告和审定财务报表
exportName。 。 。 . loadDeclarationModule 更喜欢对请求的回调
执行作用,回到 render 角色缺席。 没有
调用它导入模块定位器 。 保持实际渲染器函数可达
通过调回,所以捆绑 保留它们只目录的入口。 这个
callback是一款运行时的副车,被排除于犬类包元数据.
托管的工作流程字段、配置和模板声明要求 load
调用。 他们的渲染路径拒绝只定位器执行, 如此托管
捆绑在宣布的模块图外没有计算出进口。 这个
常规 loadDeclarationModule API 为主机保留了定位器
在这些工作流程之外加载可生成路径.
该套件在保持回放和回放DOM外部的同时会构建出出出JSX的生产.
建筑 /frontend 制造器经过生产和开发试验
消费者反应对等器,包括其加载状态和加载组件道具.
Enum 值拼写
存储器所属的 enum 值使用更低 snake_case包括组件类型、数据集状况、消费者图谱和主机贡献身份。 通知enum值保留其现有的拼写. 外部协议值,包括HTTP方法和JSON Schema关键词和格式,保留协议拼写.
查询相关记录
生成的 /studio-api 导出包括 studioViewDataSearchMembers查询
POST /studio/apps/by-slug/{slug}/views/{viewId}/data/{instanceId}/relation-members/search
与公布的视图的授权范围。 它生成的身体接受这个关系
field、过滤器、排序、光标、限制和包含路径。 过滤器和排序地址
相关计划。 前向和倒向字段使用相同的操作,包括scalar
关系(0或1个结果)。 保存生成的响应的 pagination 信封 .
一个成功的页面及其关系ID是完整的. 包括可携带
已存在的切入标记;不支持在嵌入内插入。 键入
KnowledgeReadLimitExceeded 答复需要缩小查询、页面或包括;
不要默默地剪切回复或重试未变的过大请求.
主机提供的工作流程 用户选择
WorkflowFieldComponentContext.userSelection 是可选的主机渲染器
组织成员遴选. 它接收 multiple, (中文(简体) ), value, (中文(简体) ), onChange, (中文(简体) ),
controlId, (中文(简体) ), labelledBy, (中文(简体) ), readOnly,以及 required;它返回反应节点.
值和更改中只包含用户ID(null 一个空的、,
[] 为空列表)。 主机绑定资源授权搜索和所选ID
解析; 公共捐款从未导入主机的私人拾取器或数据
客户端。 需要此渲染器的贡献必须显示不可用
如果主机省略了它,则声明不接受任意的文本输入.
目录适配器保留清晰 field.user: { multiple } 描述符在
WorkflowFieldCatalogContract。UUID 计划不会激活用户选择.