Files
visualizador_instanciados/frontend/src/selection_queries/api.ts
2026-03-23 11:13:27 -03:00

118 lines
3.8 KiB
TypeScript

import type {
GraphMeta,
SelectionQueryMeta,
SelectionQueryResult,
SelectionTriple,
SelectionTripleResult,
SelectionTripleTerm,
} from "./types";
function numberArray(value: unknown): number[] {
if (!Array.isArray(value)) return [];
const out: number[] = [];
for (const item of value) {
if (typeof item === "number") out.push(item);
}
return out;
}
function tripleTerm(value: unknown): SelectionTripleTerm | null {
if (!value || typeof value !== "object") return null;
const record = value as Record<string, unknown>;
if (typeof record.type !== "string" || typeof record.value !== "string") return null;
return {
type: record.type,
value: record.value,
lang: typeof record.lang === "string" ? record.lang : undefined,
};
}
function tripleArray(value: unknown): SelectionTriple[] {
if (!Array.isArray(value)) return [];
const out: SelectionTriple[] = [];
for (const item of value) {
if (!item || typeof item !== "object") continue;
const record = item as Record<string, unknown>;
const s = tripleTerm(record.s);
const p = tripleTerm(record.p);
const o = tripleTerm(record.o);
if (!s || !p || !o) continue;
out.push({
s,
p,
o,
subject_id: typeof record.subject_id === "number" ? record.subject_id : undefined,
predicate_id: typeof record.predicate_id === "number" ? record.predicate_id : undefined,
object_id: typeof record.object_id === "number" ? record.object_id : undefined,
});
}
return out;
}
export async function fetchSelectionQueries(signal?: AbortSignal): Promise<SelectionQueryMeta[]> {
const res = await fetch("/api/selection_queries", { signal });
if (!res.ok) throw new Error(`GET /api/selection_queries failed: ${res.status}`);
const data = await res.json();
return Array.isArray(data) ? (data as SelectionQueryMeta[]) : [];
}
export async function runSelectionQuery(
queryId: string,
selectedIds: number[],
graphMeta: GraphMeta | null,
signal: AbortSignal
): Promise<SelectionQueryResult> {
const body = {
query_id: queryId,
selected_ids: selectedIds,
node_limit: typeof graphMeta?.node_limit === "number" ? graphMeta.node_limit : undefined,
edge_limit: typeof graphMeta?.edge_limit === "number" ? graphMeta.edge_limit : undefined,
graph_query_id: typeof graphMeta?.graph_query_id === "string" ? graphMeta.graph_query_id : undefined,
};
const res = await fetch("/api/selection_query", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify(body),
signal,
});
if (!res.ok) throw new Error(`POST /api/selection_query failed: ${res.status}`);
const data = await res.json();
return {
queryId: typeof data?.query_id === "string" ? data.query_id : queryId,
selectedIds: numberArray(data?.selected_ids),
neighborIds: numberArray(data?.neighbor_ids),
};
}
export async function runSelectionTripleQuery(
queryId: string,
selectedIds: number[],
graphMeta: GraphMeta | null,
signal: AbortSignal
): Promise<SelectionTripleResult> {
const body = {
query_id: queryId,
selected_ids: selectedIds,
node_limit: typeof graphMeta?.node_limit === "number" ? graphMeta.node_limit : undefined,
edge_limit: typeof graphMeta?.edge_limit === "number" ? graphMeta.edge_limit : undefined,
graph_query_id: typeof graphMeta?.graph_query_id === "string" ? graphMeta.graph_query_id : undefined,
};
const res = await fetch("/api/selection_triples", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify(body),
signal,
});
if (!res.ok) throw new Error(`POST /api/selection_triples failed: ${res.status}`);
const data = await res.json();
return {
queryId: typeof data?.query_id === "string" ? data.query_id : queryId,
selectedIds: numberArray(data?.selected_ids),
triples: tripleArray(data?.triples),
};
}