Support complete public relationship observations for optimistic presentation hosting
This commit is contained in:
@@ -22,6 +22,8 @@ export interface InspectionTemplate {
|
||||
inputs?: PublicQueryContract;
|
||||
view?: PublicQueryContract;
|
||||
server?: PublicQueryContract;
|
||||
completeInputs?: PublicQueryContract;
|
||||
completeView?: PublicQueryContract;
|
||||
}
|
||||
/** A finite installed template per interface/lane, not a per-client query compiler.
|
||||
* Flags select public cache boundaries; normal scope identity bounds specialization. */
|
||||
@@ -54,7 +56,9 @@ export function compileInspectionTemplates(plan: ExecutionPlan) {
|
||||
.sort((a, b) => (a.id < b.id ? -1 : 1));
|
||||
if (!members.length || members.length > 128) continue;
|
||||
const template: InspectionTemplate = { interface: iface.revisionId, members: [] };
|
||||
for (const lane of ["local", "server"] as const) {
|
||||
for (const mode of ["local", "complete", "server"] as const) {
|
||||
const lane = mode === "server" ? "server" : "local";
|
||||
const complete = mode === "complete";
|
||||
const fields: unknown[] = [],
|
||||
selections: unknown[] = [],
|
||||
inputFields: Record<string, unknown> = {},
|
||||
@@ -76,7 +80,7 @@ export function compileInspectionTemplates(plan: ExecutionPlan) {
|
||||
const many = member.kind === "relationship" && ["many", "many-unique"].includes(member.cardinality);
|
||||
// Only native edges promise the relationship traversal used by the interpreter.
|
||||
if (member.kind === "relationship" && providers.some((op) => op!.binding.kind !== "edge")) continue;
|
||||
if (lane === "local" || !portable)
|
||||
if (!complete && (lane === "local" || !portable))
|
||||
template.members.push({ id: member.id, name: member.displayName, key, flag, lane, many });
|
||||
inputFields[flag] = scalar("bool");
|
||||
const field = selection(member.displayName, {
|
||||
@@ -95,18 +99,27 @@ export function compileInspectionTemplates(plan: ExecutionPlan) {
|
||||
if (member.target.kind === "interface")
|
||||
Object.assign(field, { targetInterfaceRevisionId: member.target.interfaceRevisionId });
|
||||
if (many) {
|
||||
inputFields[key + "First"] = scalar("int32");
|
||||
inputFields[key + "After"] = optional(scalar("string"));
|
||||
const bound = key + (complete ? "All" : "First");
|
||||
inputFields[bound] = scalar("int32");
|
||||
if (!complete) inputFields[key + "After"] = optional(scalar("string"));
|
||||
const keyFields = { key: scalar("string"), ...(member.keyType ? { mapKey: scalar(member.keyType) } : {}) };
|
||||
const keySelections = [selection("key"), ...(member.keyType ? [selection("mapKey")] : [])];
|
||||
Object.assign(field, {
|
||||
arguments: { first: variable(key + "First"), after: variable(key + "After") },
|
||||
arguments: complete
|
||||
? { all: variable(bound) }
|
||||
: { first: variable(bound), after: variable(key + "After") },
|
||||
selection: [
|
||||
selection("entries", { selection: [selection("key"), selection("node", { selection: [meta()] })] }),
|
||||
selection("pageInfo", { selection: [selection("hasNextPage"), selection("endCursor")] }),
|
||||
selection("entries", { selection: [...keySelections, selection("node", { selection: [meta()] })] }),
|
||||
...(complete
|
||||
? []
|
||||
: [selection("pageInfo", { selection: [selection("hasNextPage"), selection("endCursor")] })]),
|
||||
],
|
||||
});
|
||||
output = record({
|
||||
entries: { kind: "list", value: record({ key: scalar("string"), node }) },
|
||||
pageInfo: record({ hasNextPage: scalar("bool"), endCursor: optional(scalar("string")) }),
|
||||
entries: { kind: "list", value: record({ ...keyFields, node }) },
|
||||
...(complete
|
||||
? {}
|
||||
: { pageInfo: record({ hasNextPage: scalar("bool"), endCursor: optional(scalar("string")) }) }),
|
||||
});
|
||||
} else {
|
||||
Object.assign(field, { selection: [meta()] });
|
||||
@@ -147,8 +160,9 @@ export function compileInspectionTemplates(plan: ExecutionPlan) {
|
||||
},
|
||||
};
|
||||
for (const kind of lane === "local" ? (["inputs", "view"] as const) : (["server"] as const)) {
|
||||
const query = JSON.stringify([iface.revisionId, kind]);
|
||||
const sourceQuery = JSON.stringify([iface.revisionId, "inputs"]);
|
||||
const templateKey = complete ? (kind === "inputs" ? "completeInputs" : "completeView") : kind;
|
||||
const query = JSON.stringify([iface.revisionId, templateKey]);
|
||||
const sourceQuery = JSON.stringify([iface.revisionId, complete ? "completeInputs" : "inputs"]);
|
||||
const program = {
|
||||
...base,
|
||||
id: JSON.stringify([inspectionPackage, query]),
|
||||
@@ -167,7 +181,7 @@ export function compileInspectionTemplates(plan: ExecutionPlan) {
|
||||
};
|
||||
queries.push(program);
|
||||
contracts.push(contract);
|
||||
template[kind] = contract;
|
||||
template[templateKey] = contract;
|
||||
}
|
||||
}
|
||||
if (template.members.length) templates.push(template);
|
||||
|
||||
Reference in New Issue
Block a user