Scope presentation associations to PresentationMount and retain navigation queries
Generate checked navigation query pairs from closed React contracts before package checking. Retain per-type subscriptions under the logical PresentationMount and resolve cold component metadata independently of code. Keep scoped occurrence membership and idempotent local preparation in the presentation library; copy directly through state contracts without reading other PresentationMounts' source associations. Preserve normal transaction creation, pending references, portal synchronization and detach. Exercise automatic object refs in Reader queries, imported fragments and structured/aggregate results. Add heterogeneous owner-index, live dependency, cold metadata, browser ownership and latency coverage. Document measured improvements, supported query limits and qualification evidence.
This commit is contained in:
@@ -171,6 +171,12 @@ export async function compileQuery(
|
||||
visit(
|
||||
document,
|
||||
visitWithTypeInfo(projectionTypes, {
|
||||
Field(node) {
|
||||
const parent = projectionTypes.getParentType();
|
||||
const member =
|
||||
parent && generated.byName.get(parent.name)?.members.find((member) => member.displayName === node.name.value);
|
||||
if (member?.kind === "relationship") generated.target(member);
|
||||
},
|
||||
InlineFragment(node) {
|
||||
if (!node.typeCondition) return;
|
||||
const from = projectionTypes.getParentType();
|
||||
|
||||
@@ -44,6 +44,7 @@ export type SchemaRowField = { kind: "leaf"; type: ValueType } | { kind: "row";
|
||||
export interface RelationalSchemaEnvironment {
|
||||
contracts: Map<InterfaceRevisionId, InterfaceRevision>;
|
||||
target(member: RelationshipInterfaceMember): InterfaceRevisionId;
|
||||
viewable(member: RelationshipInterfaceMember): boolean;
|
||||
name(id: InterfaceRevisionId): string;
|
||||
scalar(type: ValueType): GraphQLInputType & GraphQLOutputType;
|
||||
comparison(type: ValueType): GraphQLInputObjectType;
|
||||
@@ -83,7 +84,8 @@ export function relationalSchema(env: RelationalSchemaEnvironment, document?: Do
|
||||
? env.contracts
|
||||
.get(row.interfaceRevisionId)!
|
||||
.members.filter(
|
||||
(member): member is RelationshipInterfaceMember => member.kind === "relationship" && !!member.queryRead,
|
||||
(member): member is RelationshipInterfaceMember =>
|
||||
member.kind === "relationship" && !!member.queryRead && env.viewable(member),
|
||||
)
|
||||
: [];
|
||||
const fields = (row: QueryRow): Map<string, SchemaRowField> => {
|
||||
@@ -96,6 +98,7 @@ export function relationalSchema(env: RelationalSchemaEnvironment, document?: Do
|
||||
env.contracts.get(row.interfaceRevisionId)!.members.flatMap((member): [string, SchemaRowField][] => {
|
||||
if (member.kind === "operation" || member.kind === "module" || !member.queryRead) return [];
|
||||
if (member.kind === "value") return [[member.displayName, { kind: "leaf", type: member.valueType }]];
|
||||
if (!env.viewable(member)) return [];
|
||||
if (many(member)) return [];
|
||||
return [
|
||||
[
|
||||
|
||||
@@ -150,11 +150,15 @@ export function querySchema(
|
||||
return result;
|
||||
};
|
||||
const structured = structuredQueryTypes(scalar, scalarComparison, direction);
|
||||
const viewable = (member: RelationshipInterfaceMember) =>
|
||||
member.target.kind === "interface" ||
|
||||
declaration.views.some((view) => member.target.kind === "atom" && view.atomId === member.target.atomId);
|
||||
const comparison = (type: ValueType) => structured.input(type) as GraphQLInputObjectType;
|
||||
const relational = relationalSchema(
|
||||
{
|
||||
contracts,
|
||||
target,
|
||||
viewable,
|
||||
name,
|
||||
scalar,
|
||||
comparison,
|
||||
@@ -205,6 +209,9 @@ export function querySchema(
|
||||
if (member.kind === "value") {
|
||||
fields[member.displayName] = { type: structured.output(member.valueType) };
|
||||
} else {
|
||||
// Reference-only projections need no views for unselected outgoing
|
||||
// atom relationships. Selecting one still requires its explicit view.
|
||||
if (!viewable(member)) continue;
|
||||
const targetId = target(member),
|
||||
node = object(targetId);
|
||||
if (member.cardinality === "exactly-one" || member.cardinality === "optional-one")
|
||||
|
||||
Reference in New Issue
Block a user