Implement query execution, scoped RPC enrichment, live collections, and scaffold integration

This commit is contained in:
Timothy J. Aveni
2026-09-17 14:34:16 -07:00
parent 61a410f98f
commit cd13120937
37 changed files with 4406 additions and 2647 deletions
+79 -1
View File
@@ -504,6 +504,18 @@ const collectIdentityIndexes = (
const operations = new Map<OperationId, InterfaceOperationEntry>();
for (const [memberIndex, member] of revision.members.entries()) {
const memberPath = `${path}.members[${memberIndex}]`;
if (
member.kind === "relationship" &&
member.keyType !== undefined &&
(!["string", "boolean", "int64"].includes(member.keyType) ||
!["many", "many-unique"].includes(member.cardinality))
)
issue(
issues,
"invalid-query-contract",
memberPath,
"Keyed relationships require many cardinality and string, boolean or int64 keys",
);
if (member.kind !== "operation" && member.queryRead) {
const contract = member.queryRead.execution;
const getter = member.kind === "value" ? "get" : "resolve";
@@ -984,6 +996,21 @@ const validatePackages = (
for (const [portIndex, port] of entry.dependencyPorts.entries()) {
const portPath = `${exportPath}.dependencyPorts[${portIndex}]`;
switch (port.requirement.kind) {
case "query":
if (
!indexes.packages
.get(port.requirement.packageRevisionId)
?.revision.queries?.some(
(query) => port.requirement.kind === "query" && query.id === port.requirement.queryId,
)
)
issue(
issues,
"unresolved-reference",
portPath,
`Unknown query ${port.requirement.packageRevisionId}:${port.requirement.queryId}`,
);
break;
case "state":
validateValueType(issues, port.requirement.valueType, `${portPath}.requirement.valueType`, indexes);
uniquePrimitiveList(issues, port.requirement.primitives, `${portPath}.requirement.primitives`);
@@ -1133,6 +1160,41 @@ const validateBoundDependencies = (
continue;
}
switch (requirement.kind) {
case "query": {
const selected = binding as Extract<DependencyBinding, { kind: "query" }>;
const query = params.indexes.packages
.get(requirement.packageRevisionId)
?.revision.queries?.find((query) => query.id === requirement.queryId);
if (
!query ||
selected.queryId !== requirement.queryId ||
selected.packageRevisionId !== requirement.packageRevisionId
) {
issue(issues, "invalid-dependency-binding", path, "Query port must bind its exact checked query export");
break;
}
const traversal = selected.via
? validateTraversal(
issues,
params.indexes,
params.atomId,
selected.via,
`${path}.binding.via`,
params.conformance,
)
: undefined;
const targets = selected.via
? traversal
? [...params.indexes.atoms.keys()].filter((atom) =>
atomSatisfiesConstraint(atom as AtomId, traversal.target.constraint, params.indexes.conformances),
)
: []
: [params.atomId];
for (const atom of targets)
if (!params.indexes.conformances.has(conformanceKey(atom as AtomId, query.root)))
issue(issues, "unsatisfied-interface", path, `Query root ${atom} does not conform to ${query.root}`);
break;
}
case "state": {
const stateBinding = binding as Extract<DependencyBinding, { kind: "state" }>;
const attachment = findAttachment(params.indexes, "state", stateBinding.slotId);
@@ -1583,7 +1645,8 @@ const validateConformances = (
operationEntry.member.target,
indexes.conformances,
) ||
operationEntry.member.cardinality !== projection.endpoint.cardinality
operationEntry.member.cardinality !== projection.endpoint.cardinality ||
(operationEntry.member.keyType !== undefined && operationEntry.member.keyType !== projection.endpoint.keyType)
) {
issue(
issues,
@@ -2091,6 +2154,21 @@ export const computeCapabilityClosure = (
const includeDependencies = (atomId: AtomId, dependencies: readonly BoundDependency[]) => {
for (const dependency of dependencies) {
switch (dependency.binding.kind) {
case "query": {
packages.add(dependency.binding.packageRevisionId);
const query = plan.packages
.get(dependency.binding.packageRevisionId)
?.checkedQueries?.find(
(query) => dependency.binding.kind === "query" && query.declaration.id === dependency.binding.queryId,
);
if (dependency.binding.via) attachments.add(dependency.binding.via.edgeTypeId);
for (const effect of query?.effects ?? []) {
for (const conformance of sourceConformances.values())
if (conformance.interfaceRevisionId === effect.interfaceRevisionId)
queued.push({ atomId: conformance.atomId, interfaceRevisionId: conformance.interfaceRevisionId });
}
break;
}
case "state":
attachments.add(dependency.binding.slotId);
if (dependency.binding.via) {