docs: record the forwarded-event surface and its face boundaries

Each owner package's README states which of its cordis events are forwarded and
that the declaration now lives in the client-safe ./types export. api/remotes
documents the allowlist as the single control point and the deliberate
both-faces listing of src/types.ts; development.md keeps the split-tsconfig rule
current.
This commit is contained in:
imccyu
2026-08-10 21:32:49 +08:00
parent 7c8ee81818
commit b64da061a8
16 changed files with 48 additions and 14 deletions

View File

@@ -20,6 +20,8 @@ A cancellation-aware Remote method declares `signal: AbortSignal` as its final H
Each call validates positional inputs, constructs the descriptor's exact named `args`, and sends it through `ctx.connection.rpc.call('/api', endpoint, ...)`. Generated cancellation-aware methods accept a final optional `AbortSignal`; the Client combines it with the contribution mount lifetime before calling Connection. The returned value is validated before reaching application code. Withdrawing a contribution removes its descriptors and methods together, aborts in-flight calls, and makes retained method handles reject.
`ctx.remote.$on()` subscribes to one forwarded Host event. Its legal keys are exactly the Host assembly's forwarding selection, and the listener type is the owning package's own Cordis `Events` declaration, so no second signature can drift from it. Each subscription belongs to the calling fiber and disappears with it. Delivery is one-way and follows registration order; a listener that throws is logged and isolated from the remaining listeners, which never affects the frame pump. The delivery port is not part of the Remote contract: the Client half owning the Host frame sink emits the internal `remote/host-event` Cordis event, the Remote service is its only subscriber, and an event name nobody subscribes to is dropped, since the wire carries whatever the Host selected.
Generated declaration merges provide the TypeScript API through the shared `TypeRTClientRemote` contract. The Client entry contains no Host Service or Host Cordis interface merge, and method lookup and invocation use ordinary objects and functions rather than a JavaScript Proxy.
## Model Experience
@@ -37,3 +39,4 @@ No direct effect; invoked business Services own any model-visible result.
- Only strict generated contributions can mount on the Client face. SRC markers have no Client codec or type projection.
- The package dispatches unary methods only. Incremental Session data uses a separate named-stream protocol over the same Connection.
- Lookup resolvers are configured per key; an individual Remote parameter or endpoint cannot currently select a live-only policy under the same `agent`/`session` key.
- Forwarded events reach `$on` exactly as the Host emitted them: no payload projection or redaction, no Scope-bound subscription, and no replay after a reconnect.

View File

@@ -20,6 +20,8 @@ Connection 可用时Host 入口会在 Connection 共享的 `/api` FetchHandle
每次调用都会校验位置参数,构造与描述符完全匹配的具名 `args`,再通过 `ctx.connection.rpc.call('/api', endpoint, ...)` 发送。生成的支持取消的方法接受最后一个可选 `AbortSignal`Client 会在调用 Connection 前将它与贡献项的挂载生命周期合并。返回值经过校验后才会交给应用代码。撤回贡献项会同时移除其描述符和方法、中止正在进行的调用,并使外部仍持有的方法句柄在调用时返回拒绝。
`ctx.remote.$on()` 订阅一条被转发的 Host 事件。它的合法键恰好等于 Host 装配声明的转发选择listener 类型就是事件所属包自己的 Cordis `Events` 声明,因此不存在会与之漂移的第二份签名。每个订阅归属发起调用的 fiber并随该 fiber 一起消失。投递是单向的,并按注册顺序进行;抛错的 listener 会被记录并与其余 listener 隔离,绝不影响帧泵。投递口不属于 Remote 约定:持有 Host 帧 sink 的 Client 半发射内部 Cordis 事件 `remote/host-event`Remote 服务是它唯一的订阅方,收到无人订阅的事件名即丢弃,因为 wire 上出现什么取决于 Host 的转发选择。
生成的声明合并通过共享的 `TypeRTClientRemote` 约定提供 TypeScript API。Client 入口不包含 Host 服务或 Host Cordis 接口合并;方法查找和调用使用普通对象与函数,而不使用 JavaScript Proxy。
## 模型体验
@@ -37,3 +39,4 @@ Connection 可用时Host 入口会在 Connection 共享的 `/api` FetchHandle
- Client 侧只能挂载严格模式生成的贡献项。SRC 标记不具备 Client 编解码器或类型投影。
- 该包只分发一元方法。增量会话数据通过同一个 Connection 上独立的具名流协议传输。
- lookup resolver 按 key 配置;当前无法让单个 Remote 参数或 endpoint 在同一 `agent`/`session` key 下选择 live-only 策略。
- 被转发的事件原样到达 `$on`:没有载荷投影或脱敏,不支持 Scope 化订阅,重连后也不重放。