Generalize live field bindings and use them for Studio canvas gestures

This commit is contained in:
Timothy J. Aveni
2026-09-28 11:12:11 -07:00
parent 696023b4ba
commit 0ace71eae6
13 changed files with 1766 additions and 1586 deletions
+21 -5
View File
@@ -17,6 +17,7 @@ export interface PublicOperationContract {
execution: ExecutionContract;
input: unknown;
output: unknown;
fieldPolicy?: "register" | "crdt";
}
export function publicOperationContract(
iface: InterfaceRevision,
@@ -29,7 +30,20 @@ export function publicOperationContract(
"Expected a closed interface call operation",
);
const execution = operation.execution ?? { kind: "remote" };
const member = iface.members.find((m) => m.operations.includes(operation))!;
const fieldPolicy =
member.kind === "value" &&
operation.scope !== "class" &&
execution.kind === "transaction" &&
execution.targets.includes("browser")
? operation.displayName === "edit"
? "crdt"
: member.nativeField && operation.displayName === "set"
? "register"
: undefined
: undefined;
return {
...(fieldPolicy ? { fieldPolicy } : {}),
interface: iface.revisionId,
operation: operation.id,
scope: operation.scope ?? "object",
@@ -116,15 +130,17 @@ export function generateInterfaceClientBindings(
}
const operations = member.operations
.filter((op) => op.mode === "call")
.map(
(op) =>
`${JSON.stringify(op.displayName)}: defineInterfaceOperation<${tsType(op.inputType)}, ${tsType(op.outputType)}, ${JSON.stringify(publicOperationContract(iface, op).execution)}>(${JSON.stringify(publicOperationContract(iface, op))})`,
);
.map((op) => {
const contract = publicOperationContract(iface, op);
return contract.fieldPolicy && member.kind === "value"
? `${JSON.stringify(op.displayName)}: defineFieldOperation<${tsType(member.valueType)}, ${JSON.stringify(contract.fieldPolicy)}, ${JSON.stringify(contract.execution)}>(${JSON.stringify(contract)})`
: `${JSON.stringify(op.displayName)}: defineInterfaceOperation<${tsType(op.inputType)}, ${tsType(op.outputType)}, ${JSON.stringify(contract.execution)}>(${JSON.stringify(contract)})`;
});
return `${JSON.stringify(member.displayName)}: {${operations.join(",\n")}}`;
});
return `${JSON.stringify(alias)}: {${members.join(",\n")}}`;
});
return `// Generated from imported interface contracts. Regenerate; do not edit.\nimport { defineModuleMember, defineInterfaceOperation, type PreparedChange, type ManagedReference } from ${JSON.stringify(runtimeModule)};\nexport const interfaces = {${entries.join(",\n")}} as const;\n`;
return `// Generated from imported interface contracts. Regenerate; do not edit.\nimport { defineModuleMember, defineInterfaceOperation, defineFieldOperation, type PreparedChange, type ManagedReference } from ${JSON.stringify(runtimeModule)};\nexport const interfaces = {${entries.join(",\n")}} as const;\n`;
}
export function generatePackageQueryClientBindings(