import type { AtomId, InterfaceRevisionId, MemberId, ValueType } from "../capability-model/types.js"; export type QueryUse = "select" | "predicate" | "order"; export interface QueryAllowance { interfaceRevisionId: InterfaceRevisionId; memberId: MemberId; uses: QueryUse[]; reason: string; } export interface QueryBudgets { rows: number; depth: number; resultBytes: number; candidates: number; rpcCalls: number; concurrency: number; deadlineMs: number; } export const defaultQueryBudgets: Readonly = Object.freeze({ rows: 100, depth: 8, resultBytes: 1048576, candidates: 100, rpcCalls: 200, concurrency: 8, deadlineMs: 10000, }); export interface QueryDeclaration { id: string; displayName: string; root: InterfaceRevisionId; document: string; operation: string; fragments: string[]; views: { atomId: AtomId; interfaceRevisionId: InterfaceRevisionId }[]; allowances: QueryAllowance[]; budgets: QueryBudgets; watch: boolean; polling?: { intervalMs: number; reason: string }; } export interface QueryFieldEffect { interfaceRevisionId: InterfaceRevisionId; memberId: MemberId; uses: QueryUse[]; execution: "native" | "rpc-permitted"; } export interface QuerySourceLocation { file: string; line: number; column: number; } export class QueryCompileError extends Error { constructor( readonly code: string, message: string, readonly location?: QuerySourceLocation, ) { super(message); this.name = "QueryCompileError"; } } export interface CheckedQuery { declaration: QueryDeclaration; definitionDigest: string; /** Fixed, validated document: never supplied by runtime callers. */ document: string; schema: string; variables: ValueType; output: ValueType; effects: QueryFieldEffect[]; selection: QuerySelection[]; variableDefaults: Record; sourceFiles: string[]; } export type QueryArgument = | { kind: "variable"; name: string } | { kind: "literal"; value: string | number | boolean | null } | { kind: "list"; values: QueryArgument[] } | { kind: "object"; fields: Record }; export interface QuerySelection { name: string; key: string; interfaceRevisionId?: InterfaceRevisionId; memberId?: MemberId; targetInterfaceRevisionId?: InterfaceRevisionId; conditions: { include: boolean; value: QueryArgument }[]; arguments: Record; selection: QuerySelection[]; }