Skip to content

Commit 80b789c

Browse files
committed
chore: update rfc
1 parent 8ee97cf commit 80b789c

1 file changed

Lines changed: 117 additions & 105 deletions

File tree

docs/agent-runtime/rfc-openruntime.md

Lines changed: 117 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -133,29 +133,9 @@ Target Registry / Snapshot / Event Log / Action Registry
133133
Target Registry 表示页面里有哪些对象可以被 Agent 引用或等待。
134134

135135
```ts
136-
type RuntimeObjectType =
137-
| 'app'
138-
| 'route'
139-
| 'loader'
140-
| 'component'
141-
| 'form'
142-
| 'field'
143-
| 'remote'
144-
| 'expose'
145-
| 'shared'
146-
| 'sub-app'
147-
| 'business'
148-
| 'custom';
149-
150-
type RuntimeStatus =
151-
| 'idle'
152-
| 'loading'
153-
| 'pending'
154-
| 'success'
155-
| 'ready'
156-
| 'blocked'
157-
| 'error'
158-
| 'inactive';
136+
type RuntimeObjectType = string;
137+
138+
type RuntimeStatus = string;
159139

160140
type RuntimeError = {
161141
message: string;
@@ -170,7 +150,7 @@ type RegisterTargetInput = {
170150
source: string;
171151
label?: string;
172152
description?: string;
173-
statuses?: RuntimeStatus[];
153+
statuses: RuntimeStatus[];
174154
params?: RuntimeTargetParam[];
175155
matcher?: RuntimeTargetMatcher;
176156
data?: unknown;
@@ -189,30 +169,31 @@ type RuntimeTargetMatcher = {
189169
};
190170
```
191171

192-
`id``type``source` 是必填字段。`statuses` 不传时,Runtime Center 按 `type` 补默认状态。
172+
OpenRuntime Core 不内置固定的 `RuntimeObjectType``RuntimeStatus` 枚举。`type``statuses` 都由 `registerTarget` 显式声明,Runtime Center 只把它们当作字符串处理。`statuses` 不能为空。
173+
174+
因此同样是 route、remote、business,不同框架或业务可以声明更准确的状态集合:
193175

194-
默认状态表:
176+
```ts
177+
runtime.registerTarget({
178+
id: 'route:/route-a',
179+
type: 'modern.route',
180+
source: 'modern-js',
181+
statuses: ['loading', 'ready', 'blocked', 'error', 'inactive'],
182+
});
195183

196-
| type | 默认 statuses |
197-
| --- | --- |
198-
| `app` | `loading` / `ready` / `blocked` / `error` / `inactive` |
199-
| `route` | `loading` / `ready` / `blocked` / `error` / `inactive` |
200-
| `component` | `loading` / `ready` / `blocked` / `error` / `inactive` |
201-
| `sub-app` | `idle` / `loading` / `ready` / `blocked` / `error` / `inactive` |
202-
| `business` | `pending` / `ready` / `blocked` / `error` / `inactive` |
203-
| `loader` | `idle` / `loading` / `pending` / `success` / `blocked` / `error` / `inactive` |
204-
| `remote` | `idle` / `loading` / `success` / `blocked` / `error` / `inactive` |
205-
| `expose` | `idle` / `loading` / `success` / `blocked` / `error` / `inactive` |
206-
| `shared` | `idle` / `success` / `blocked` / `error` / `inactive` |
207-
| `form` | `idle` / `pending` / `success` / `blocked` / `error` / `inactive` |
208-
| `field` | `idle` / `pending` / `success` / `blocked` / `error` / `inactive` |
209-
| `custom` | 默认允许全部 `RuntimeStatus`,接入方建议显式传 `statuses` |
184+
runtime.registerTarget({
185+
id: 'remote:cloud-console',
186+
type: 'mf.remote',
187+
source: 'module-federation',
188+
statuses: ['idle', 'loading', 'success', 'error'],
189+
});
190+
```
210191

211-
`ready` 只推荐用于表达“现在可以继续使用”的对象,例如 app、route、component、sub-app 和 business。loader、remote、expose、shared 这类过程或依赖对象应该用 `success` 表示完成
192+
SDK 可以提供常用 helper 或常量,降低接入成本;但这些只是 helper,不是 Core 的内置校验规则。最终允许哪些 `type``status`,以 `registerTarget` 的声明为准
212193

213194
`unregisterTarget(targetId)` 用于目标不再可被引用或等待的场景,例如动态卸载的子应用、销毁的业务区域或失效的自定义 target。框架静态路由、固定 remote、固定 shared 通常不需要注销,只需要通过 Snapshot 更新为 `inactive``blocked``error`
214195

215-
如果 `updateSnapshot` 更新了未注册过的 id,Runtime Center 可以临时创建 inferred target,避免状态丢失;开发环境应该给出 warning,提醒框架或业务在更早时机注册
196+
如果 `updateSnapshot` 更新了未注册过的 id,Runtime Center 应拒绝本次更新,并在开发环境给出 warning,提醒框架或业务在更早时机调用 `registerTarget`
216197

217198
## Snapshot
218199

@@ -236,38 +217,12 @@ type RuntimeSnapshotTarget = {
236217
updatedAt: number;
237218

238219
dependsOn?: string[];
239-
contains?: string[];
240-
loads?: string[];
241-
renders?: string[];
242-
provides?: string[];
243-
shares?: string[];
244-
customRelations?: RuntimeInlineRelation[];
245-
};
246-
247-
type RuntimeInlineRelation = {
248-
type: 'custom';
249-
relation: string;
250-
to: string;
251-
description?: string;
252-
data?: unknown;
253220
};
254221
```
255222

256223
`targets` 使用 target id 映射当前状态。`updateSnapshot``id` upsert,同一个 `id` 再次更新时只替换当前状态和相关字段,不追加历史 item。历史过程由 events 记录。
257224

258-
常见关系直接作为 target 字段表达,方向统一是“当前 target 指向相关 target”。
259-
260-
| 字段 | 含义 |
261-
| --- | --- |
262-
| `contains` | 当前 target 包含哪些 target |
263-
| `dependsOn` | 当前 target 依赖哪些 target |
264-
| `loads` | 当前 target 加载哪些 target |
265-
| `renders` | 当前 target 渲染哪些 target |
266-
| `provides` | 当前 target 提供哪些 target |
267-
| `shares` | 当前 target 共享或使用哪些 target |
268-
| `customRelations` | 业务自定义关系 |
269-
270-
`loads` 的方向是当前 target 加载了谁。例如 `route:/home``loads: ['remote:cloudConsoleProvider']` 表示 `/home` 路由加载了这个 remote。
225+
`dependsOn` 表示当前 target 是否 ready 依赖哪些其他 target。Agent 可以沿着 `dependsOn` 查找 blocker。
271226

272227
`latestEventId` 表示这份 Snapshot 截止到哪个 event,Agent 后续可以用 `getEvents({ since: latestEventId })` 读取增量事件。`capturedAt` 表示 Snapshot 生成时间,Bridge 返回断开页面的最后状态时也可以让 Agent 判断状态是否过期。
273228

@@ -284,35 +239,80 @@ type RuntimeEvent = {
284239
targetId?: string;
285240
actionName?: string;
286241
status?: RuntimeStatus;
287-
relation?: RuntimeRelationEvent;
288-
data?: unknown;
242+
payload?: unknown;
289243
error?: RuntimeError;
290244
};
245+
```
291246

292-
type RuntimeRelationEvent =
293-
| RuntimeBuiltInRelationEvent
294-
| RuntimeCustomRelationEvent;
295-
296-
type RuntimeBuiltInRelationEvent = {
297-
from: string;
298-
to: string;
299-
field:
300-
| 'dependsOn'
301-
| 'contains'
302-
| 'loads'
303-
| 'renders'
304-
| 'provides'
305-
| 'shares';
306-
};
247+
`payload` 的结构由 `type` 决定。例如 `snapshot.updated` 的 payload 是被接受的 `UpdateSnapshotInput``action.started` 的 payload 是 action 入参,`action.success` 的 payload 是 action 返回值。
307248

308-
type RuntimeCustomRelationEvent = {
309-
from: string;
310-
type: 'custom';
311-
relation: string;
312-
to: string;
313-
description?: string;
314-
data?: unknown;
315-
};
249+
例如:
250+
251+
```ts
252+
runtime.updateSnapshot({
253+
id: 'route:/a',
254+
type: 'modern.route',
255+
source: 'modern-js',
256+
status: 'loading',
257+
dependsOn: ['remote:B'],
258+
});
259+
```
260+
261+
会自动记录:
262+
263+
```json
264+
{
265+
"id": 1,
266+
"type": "snapshot.updated",
267+
"source": "modern-js",
268+
"timestamp": 1780000001,
269+
"targetId": "route:/a",
270+
"status": "loading",
271+
"payload": {
272+
"id": "route:/a",
273+
"type": "modern.route",
274+
"source": "modern-js",
275+
"status": "loading",
276+
"dependsOn": ["remote:B"]
277+
}
278+
}
279+
```
280+
281+
`runAction` 也会自动记录 event:
282+
283+
```ts
284+
await runtime.runAction('selectRegion', {
285+
province: 'zhejiang',
286+
city: 'hangzhou',
287+
});
288+
```
289+
290+
会自动记录:
291+
292+
```json
293+
[
294+
{
295+
"id": 2,
296+
"type": "action.started",
297+
"source": "business",
298+
"timestamp": 1780000002,
299+
"actionName": "selectRegion",
300+
"payload": {
301+
"province": "zhejiang",
302+
"city": "hangzhou"
303+
}
304+
},
305+
{
306+
"id": 3,
307+
"type": "action.success",
308+
"source": "business",
309+
"timestamp": 1780000003,
310+
"actionName": "selectRegion",
311+
"payload": {
312+
"selected": true
313+
}
314+
}
315+
]
316316
```
317317

318318
第一版只记录关键运行态变化,例如 action start / success / error、route change、loader start / success / redirect / error、remote / expose / shared 状态变化、component ready / error、business ready / blocked。
@@ -434,6 +434,23 @@ runtime.unregisterAction(actionName);
434434
runtime.runAction(actionName, payload?);
435435
```
436436
437+
#### registerTarget
438+
439+
```ts
440+
runtime.registerTarget(target: RegisterTargetInput);
441+
runtime.unregisterTarget(targetId: string);
442+
```
443+
444+
`registerTarget` 用来提前声明页面里可以被 Agent 引用或等待的目标。它回答的是“有什么可以等”,不是“现在是什么状态”。
445+
446+
调用方必须在注册时声明 `type``statuses`。OpenRuntime Core 不会为 route、remote、business 等对象补内置状态。
447+
448+
框架 adapter 应该在自己已经知道目标的时候尽早注册,例如 Modern.js 在路由表生成后注册 route target,MF 在 remotes 配置可用后注册 remote / expose / shared target,Garfish 在子应用注册信息可用后注册 sub-app target。
449+
450+
调用 `registerTarget` 不会让这个 target 出现在 Snapshot 里。只有后续调用 `updateSnapshot` 写入当前状态后,它才会出现在 `snapshot.targets` 中。
451+
452+
`unregisterTarget` 用来注销不再可引用或等待的目标。如果这个 target 上还有等待任务,相关 `waitFor` 应直接返回失败。
453+
437454
#### connectBridge
438455
439456
页面侧连接 Bridge 的第一版 API:
@@ -469,21 +486,15 @@ type UpdateSnapshotInput = {
469486
data?: unknown;
470487
error?: RuntimeError;
471488
dependsOn?: string[];
472-
contains?: string[];
473-
loads?: string[];
474-
renders?: string[];
475-
provides?: string[];
476-
shares?: string[];
477-
customRelations?: RuntimeInlineRelation[];
478489
};
479490
```
480491
481-
必填字段只有 `id``status``type` 默认是 `business``source` 默认是 `business`
492+
必填字段只有 `id``status``type` 不再有默认值;如果传入 `type`,必须和已注册 target 的 `type` 一致。`source` 默认可以由 Runtime Client 补齐,例如业务侧默认 `business`,Modern.js / MF / Garfish adapter 使用自己的 source
482493
483494
`updateSnapshot` 必须符合 target 声明的状态范围:
484495
485496
- 如果 `id` 已注册,`status` 必须在该 target 的 `statuses` 中。
486-
- 如果 `id` 未注册,Runtime Center 可以创建 inferred target,并使用该 `type` 的默认 statuses
497+
- 如果 `id` 未注册,本次更新被拒绝,Snapshot 不变
487498
- 如果 `status` 不在允许范围内,本次更新被拒绝,Snapshot 不变。
488499
- 被拒绝的更新需要记录 `snapshot.update.rejected` event。
489500
- 第一版不引入 strict mode,也不因为校验失败 throw,避免影响页面正常运行。
@@ -523,7 +534,6 @@ type RuntimeTargetDescriptor = {
523534
params?: RuntimeTargetParam[];
524535
matcher?: RuntimeTargetMatcher;
525536
data?: unknown;
526-
inferred?: boolean;
527537
registeredAt: number;
528538
updatedAt: number;
529539
};
@@ -533,6 +543,8 @@ getTargets(query?: GetTargetsQuery): RuntimeTargetDescriptor[];
533543
534544
`getTargets(query?)` 返回 Target Registry 里的可发现目标,不是当前状态。它告诉 Agent “有哪些 target 可以被引用或等待”。当前状态仍然通过 `getSnapshot(query?)``waitFor()` 判断。
535545
546+
`status``getTargets` 中匹配的是 target 注册时声明的 `statuses`,不是当前运行状态。如果要按当前状态过滤,应使用 `getSnapshot(query?)`
547+
536548
`query` 第一版只匹配 target 的 `id``label``description`,大小写不敏感,使用 `includes` 匹配,不匹配 `data`
537549
538550
#### getSnapshot
@@ -577,13 +589,13 @@ type GetEventsResult = {
577589
getEvents(query?: GetEventsQuery): GetEventsResult;
578590
```
579591
580-
`since` 表示只读取 `id > since` 的事件。`targetId` 会匹配普通事件里的 `targetId`,也会匹配关系事件里的 `from``to`
592+
`since` 表示只读取 `id > since` 的事件。`targetId` 只匹配事件里的 `targetId`。第一版不单独记录关系事件,依赖变化会出现在 `snapshot.updated``payload.dependsOn`
581593
582594
默认按事件发生顺序返回。如果没有传 `since`,默认只取最近一批事件,第一版默认 `limit` 可以是 100。`truncated: true` 表示结果被截断。
583595
584596
`latestEventId` 表示当前 Event Log 最新 event id。即使本次查询没有返回事件,也可以用它作为下一次增量读取的起点。
585597
586-
`getEvents` 不做全文搜索,也不匹配 `data`
598+
`getEvents` 不做全文搜索,也不匹配 `payload`
587599
588600
#### getActions
589601

0 commit comments

Comments
 (0)