fix(typert): preserve remote lookup semantics

This commit is contained in:
imccyu
2026-08-07 14:51:49 +08:00
parent 2fe4a53557
commit d941350227
35 changed files with 425 additions and 65 deletions
+2 -2
View File
@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write packages/typert/type-meta/README.md
README.md: 245df305efcf711486b2d3f32e40a8b415f2682e
README.zh.md: 592aa5d027a52a7a277a90ba5d51f19101f055f6
README.md: b394c843409e840b75bbb08b128614379e528001
README.zh.md: 5bd9bb18289a0320e0603d8b373e60d7f1e3c7e5
+1 -1
View File
@@ -20,7 +20,7 @@ Decorator initializers retain markers in a module-private `WeakMap` keyed by the
Business packages extend `TypeRTLookupMap` and `TypeRTContextMap` to associate Host objects or scoped Contexts with their wire identities. Generated artifacts extend `TypeRTRemoteMap`, `TypeRTRemoteContextMap`, and `TypeRTRemoteNamespaceMap` so Client imports expose only selected Remote methods. `InvocationDescriptor` is the shared runtime form consumed by the registry, Gateway, and Client API.
Lookup and Context packages own both sides of their contract: declaration merging supplies the static association, while runtime providers register identity resolution with `ctx.typert`. Strict codecs carry generated schemas; `src-json` codecs identify the weaker source-launch path.
Lookup and Context packages own both sides of their contract: declaration merging supplies the static association, while runtime providers register identity resolution with `ctx.typert`. A lookup provider supplies the stable declaration and default resolver, while Host composition may separately configure a synchronous or asynchronous resolver; policy rejections may use `TypeRTLookupFailure` to carry a failure value owned by the boundary adapter. Strict codecs carry generated schemas; `src-json` codecs identify the weaker source-launch path.
## Model Experience
+1 -1
View File
@@ -20,7 +20,7 @@ Host 方法通过将 `signal: AbortSignal` 声明为最后一个参数来启用
业务包扩展 `TypeRTLookupMap` 和 `TypeRTContextMap`,以关联 Host 对象或作用域 Context 与其协议身份。生成的产物扩展 `TypeRTRemoteMap`、`TypeRTRemoteContextMap` 和 `TypeRTRemoteNamespaceMap`,使 Client 导入后仅暴露选定的 Remote 方法。`InvocationDescriptor` 是供注册表、Gateway 和 Client API 使用的共享运行时形式。
查找包与 Context 包同时负责其契约的两侧:声明合并提供静态关联,运行时提供方则向 `ctx.typert` 注册身份解析。严格编解码器携带生成的 schema;`src-json` 编解码器标识约束更弱的源码启动路径。
查找包与 Context 包同时负责其契约的两侧:声明合并提供静态关联,运行时提供方则向 `ctx.typert` 注册身份解析。lookup provider 提供稳定声明与默认 resolver,Host 组合可以另行配置同步或异步 resolver;策略拒绝可用 `TypeRTLookupFailure` 携带由边界适配器拥有的失败值。严格编解码器携带生成的 schema;`src-json` 编解码器标识约束更弱的源码启动路径。
## 模型体验
+20
View File
@@ -18,6 +18,25 @@ export function isTypeRTRemoteSegment(value: string): boolean {
return value !== '.' && value !== '..' && TYPERT_REMOTE_SEGMENT_PATTERN.test(value)
}
/**
* A lookup policy rejection whose typed payload belongs to the active boundary adapter.
* Gateway adapters preserve this payload instead of collapsing it into an infrastructure failure.
*/
export class TypeRTLookupFailure<Failure = unknown> extends Error {
/** Adapter-owned failure returned to the caller. */
readonly failure: Failure
/**
* Wrap one adapter failure without exposing the rejected identity.
* @param failure - typed failure owned by the active boundary adapter.
*/
constructor(failure: Failure) {
super('TypeRT lookup policy rejected the requested identity')
this.name = 'TypeRTLookupFailure'
this.failure = failure
}
}
export type {
InvocationDescriptor,
InvocationParameterDescriptor,
@@ -36,6 +55,7 @@ export type {
TypeRTLookupHost,
TypeRTLookupMap,
TypeRTLookupProvider,
TypeRTLookupResolver,
TypeRTLookupRegistry,
TypeRTLookupWire,
TypeRTRemoteContextApi,
+27 -4
View File
@@ -176,7 +176,16 @@ export interface TypeRTRemoteContribution {
readonly descriptors: readonly InvocationDescriptor[]
}
/** Runtime resolver for one declared Host object lookup. */
/**
* Resolve one validated wire identity, synchronously or asynchronously.
* @param id - validated wire identity.
* @returns the Host object, or `undefined` when unavailable.
*/
export type TypeRTLookupResolver<Host = unknown, Wire = unknown> = (
id: Wire,
) => Host | undefined | Promise<Host | undefined>
/** Runtime provider for one declared Host object lookup. */
export interface TypeRTLookupProvider<Host = unknown, Wire = unknown> {
/** Source parameter name recognized by the SRC weak parser. */
readonly parameter: string
@@ -187,11 +196,11 @@ export interface TypeRTLookupProvider<Host = unknown, Wire = unknown> {
/** Canonical wire type symbol used by strict generation. */
readonly wireTypeSymbol: string
/**
* Resolve a wire identity to the current live Host object.
* Resolve a wire identity through the provider's default policy.
* @param id - validated wire identity.
* @returns the live object, or `undefined` when it is unavailable.
* @returns the object, `undefined` when unavailable, or either asynchronously.
*/
resolve(id: Wire): Host | undefined
resolve(id: Wire): Host | undefined | Promise<Host | undefined>
}
/** Stable wire declaration retained after a lookup provider unloads. */
@@ -304,6 +313,20 @@ export interface TypeRTLookupRegistry {
TypeRTLookupWire<TypeRTLookupMap[K]>
>,
): TypeRTDisposer
/**
* Replace one provider's default resolution policy while this contribution is active.
* Configuration may precede provider registration; without a live provider, `get()` remains unavailable.
* @param key - lookup key whose wire declaration remains provider-owned.
* @param resolver - composition-owned resolver used by every lookup of this key.
* @returns disposer restoring the provider's default resolver.
*/
configure<K extends StringKeyOf<TypeRTLookupMap>>(
key: K,
resolver: TypeRTLookupResolver<
TypeRTLookupHost<TypeRTLookupMap[K]>,
TypeRTLookupWire<TypeRTLookupMap[K]>
>,
): TypeRTDisposer
/**
* Look up one provider by runtime key.
* @param key - descriptor lookup key.