Files
quixos-protocol/src/capability-model/forwarding.ts
T

37 lines
1.4 KiB
TypeScript
Raw Normal View History

import type {
AtomId,
Binding,
Conformance,
InterfaceRevisionId,
OperationBinding,
OperationId,
WorkspaceRevision,
} from "./types.js";
export type ConcreteBinding = Exclude<Binding, { kind: "interface" }>;
export type ResolvedBinding = { conformance: Conformance; entry: OperationBinding; binding: ConcreteBinding };
/** Follow public operations on the same receiver, never private attachment names. */
export function resolveForwardedBinding(
workspace: Pick<WorkspaceRevision, "conformances">,
atomId: AtomId,
interfaceRevisionId: InterfaceRevisionId,
operationId: OperationId,
): ResolvedBinding {
const visited = new Set<string>();
for (;;) {
const key = `${interfaceRevisionId}\0${operationId}`;
if (visited.has(key)) throw new Error(`Forwarding cycle at ${interfaceRevisionId}/${operationId}`);
visited.add(key);
const conformance = workspace.conformances.find(
(c) => c.atomId === atomId && c.interfaceRevisionId === interfaceRevisionId,
);
const entry = conformance?.operationBindings.find((b) => b.operationId === operationId);
if (!conformance || !entry)
throw new Error(`Missing forwarding target ${atomId} as ${interfaceRevisionId}/${operationId}`);
if (entry.binding.kind !== "interface") return { conformance, entry, binding: entry.binding };
interfaceRevisionId = entry.binding.interfaceRevisionId;
operationId = entry.binding.operationId;
}
}