Compile and dispatch authoritative acceptance hooks with target-specific package roots

This commit is contained in:
Timothy J. Aveni
2026-09-20 22:05:59 -07:00
parent 1e69b0e662
commit 266d2d98d0
16 changed files with 3112 additions and 2701 deletions
+3
View File
@@ -257,6 +257,8 @@ export interface DependencyPort {
}
interface PackageExportBase {
/** Required authoritative snapshot export in this package. */
acceptanceExportId?: PackageExportId;
execution?: ExecutionContract;
id: PackageExportId;
displayName: string;
@@ -375,6 +377,7 @@ export type Binding =
packageRevisionId: PackageRevisionId;
exportId: PackageExportId;
dependencies: BoundDependency[];
acceptanceDependencies?: BoundDependency[];
};
export interface OperationBinding {
+40
View File
@@ -961,6 +961,32 @@ const validatePackages = (
const exportPath = `${path}.exports[${exportIndex}]`;
validateValueType(issues, entry.inputType, `${exportPath}.inputType`, indexes);
validateValueType(issues, entry.outputType, `${exportPath}.outputType`, indexes);
if (entry.acceptanceExportId !== undefined) {
const check = revision.exports.find((candidate) => candidate.id === entry.acceptanceExportId);
if (
entry.execution?.kind !== "transaction" ||
!entry.execution.targets.includes("server") ||
!check ||
check.execution?.kind !== "snapshot" ||
check.execution.targets.length !== 1 ||
check.execution.targets[0] !== "server" ||
check.acceptanceExportId !== undefined ||
entry.kind !== check.kind ||
entry.kind === "constructor" ||
!valueTypesEqual(entry.inputType, check.inputType) ||
!valueTypesEqual(check.outputType, valueType.unit) ||
(entry.kind === "operation" &&
(check.kind !== "operation" ||
check.mode !== "call" ||
!isDeepStrictEqual(entry.receiverRequirement, check.receiverRequirement)))
)
issue(
issues,
"invalid-operation",
`${exportPath}.acceptanceExportId`,
"Acceptance requires a server snapshot export with matching kind, receiver and input, unit output, and no further acceptance hook",
);
}
if (entry.kind === "operation") {
validateOperationEventShape(issues, entry, exportPath);
if (entry.eventType) {
@@ -1862,6 +1888,20 @@ const validateConformances = (
requirementGraph,
graphSourceKey: key,
});
const check = packageEntry.exports.get(packageExport.acceptanceExportId!);
if (check) {
validateBoundDependencies(issues, {
dependencies: binding.acceptanceDependencies ?? [],
dependencyPorts: check.dependencyPorts,
atomId: conformance.atomId,
conformance,
path: `${bindingPath}.binding.acceptance`,
indexes,
requirementGraph,
graphSourceKey: key,
});
} else if (binding.acceptanceDependencies !== undefined)
issue(issues, "invalid-package-binding", bindingPath, "Acceptance ports require a declared acceptance export");
}
for (const member of interfaceEntry.revision.members) {