mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-07-07 12:22:11 +02:00
178 lines
5.3 KiB
TypeScript
178 lines
5.3 KiB
TypeScript
import { useMemo } from "react";
|
|
import { useTriples } from "@trustgraph/react-state";
|
|
import { COLLECTION } from "../config";
|
|
const RDF_TYPE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type";
|
|
const RDFS_LABEL = "http://www.w3.org/2000/01/rdf-schema#label";
|
|
const RDFS_DOMAIN = "http://www.w3.org/2000/01/rdf-schema#domain";
|
|
const RDFS_RANGE = "http://www.w3.org/2000/01/rdf-schema#range";
|
|
const RDFS_COMMENT = "http://www.w3.org/2000/01/rdf-schema#comment";
|
|
const OWL_CLASS = "http://www.w3.org/2002/07/owl#Class";
|
|
const OWL_OBJECT_PROPERTY = "http://www.w3.org/2002/07/owl#ObjectProperty";
|
|
const OWL_DATATYPE_PROPERTY = "http://www.w3.org/2002/07/owl#DatatypeProperty";
|
|
|
|
// Helper to extract value from a Term
|
|
function getTermValue(term: { t: string; i?: string; v?: string }): string {
|
|
if (term.t === "i") return term.i || "";
|
|
if (term.t === "l") return term.v || "";
|
|
return "";
|
|
}
|
|
|
|
// Helper to get local name from URI
|
|
function getLocalName(uri: string): string {
|
|
const hashIndex = uri.lastIndexOf("#");
|
|
const slashIndex = uri.lastIndexOf("/");
|
|
const index = Math.max(hashIndex, slashIndex);
|
|
return index >= 0 ? uri.substring(index + 1) : uri;
|
|
}
|
|
|
|
export interface OntologyClass {
|
|
uri: string;
|
|
label: string;
|
|
comment?: string;
|
|
}
|
|
|
|
export interface OntologyProperty {
|
|
uri: string;
|
|
label: string;
|
|
domain?: string;
|
|
range?: string;
|
|
}
|
|
|
|
export interface OntologySchema {
|
|
classes: OntologyClass[];
|
|
objectProperties: OntologyProperty[];
|
|
datatypeProperties: OntologyProperty[];
|
|
// Sets for quick lookup
|
|
objectPropertyUris: Set<string>;
|
|
datatypePropertyUris: Set<string>;
|
|
}
|
|
|
|
export function useOntologySchema() {
|
|
// Query for classes
|
|
const classTriples = useTriples({
|
|
p: { t: "i", i: RDF_TYPE },
|
|
o: { t: "i", i: OWL_CLASS },
|
|
limit: 100,
|
|
collection: COLLECTION,
|
|
});
|
|
|
|
// Query for object properties
|
|
const objectPropertyTriples = useTriples({
|
|
p: { t: "i", i: RDF_TYPE },
|
|
o: { t: "i", i: OWL_OBJECT_PROPERTY },
|
|
limit: 100,
|
|
collection: COLLECTION,
|
|
});
|
|
|
|
// Query for datatype properties
|
|
const datatypePropertyTriples = useTriples({
|
|
p: { t: "i", i: RDF_TYPE },
|
|
o: { t: "i", i: OWL_DATATYPE_PROPERTY },
|
|
limit: 100,
|
|
collection: COLLECTION,
|
|
});
|
|
|
|
// Query for all triples to get labels, domains, ranges
|
|
const allTriples = useTriples({
|
|
limit: 1000,
|
|
collection: COLLECTION,
|
|
});
|
|
|
|
const isLoading = classTriples.isLoading || objectPropertyTriples.isLoading ||
|
|
datatypePropertyTriples.isLoading || allTriples.isLoading;
|
|
const isError = classTriples.isError || objectPropertyTriples.isError ||
|
|
datatypePropertyTriples.isError || allTriples.isError;
|
|
const error = classTriples.error || objectPropertyTriples.error ||
|
|
datatypePropertyTriples.error || allTriples.error;
|
|
|
|
const schema = useMemo((): OntologySchema | undefined => {
|
|
if (isLoading) return undefined;
|
|
|
|
// Build a map of URI -> metadata from all triples
|
|
const metadata = new Map<string, { label?: string; domain?: string; range?: string; comment?: string }>();
|
|
|
|
for (const triple of allTriples.triples || []) {
|
|
const subject = getTermValue(triple.s);
|
|
const predicate = getTermValue(triple.p);
|
|
const value = getTermValue(triple.o);
|
|
|
|
if (!metadata.has(subject)) {
|
|
metadata.set(subject, {});
|
|
}
|
|
const meta = metadata.get(subject)!;
|
|
|
|
if (predicate === RDFS_LABEL) {
|
|
meta.label = value;
|
|
} else if (predicate === RDFS_DOMAIN) {
|
|
meta.domain = value;
|
|
} else if (predicate === RDFS_RANGE) {
|
|
meta.range = value;
|
|
} else if (predicate === RDFS_COMMENT) {
|
|
meta.comment = value;
|
|
}
|
|
}
|
|
|
|
// Build classes list
|
|
const classes: OntologyClass[] = [];
|
|
for (const triple of classTriples.triples || []) {
|
|
const uri = getTermValue(triple.s);
|
|
const meta = metadata.get(uri) || {};
|
|
classes.push({
|
|
uri,
|
|
label: meta.label || getLocalName(uri),
|
|
comment: meta.comment,
|
|
});
|
|
}
|
|
|
|
// Build object properties list
|
|
const objectProperties: OntologyProperty[] = [];
|
|
const objectPropertyUris = new Set<string>();
|
|
for (const triple of objectPropertyTriples.triples || []) {
|
|
const uri = getTermValue(triple.s);
|
|
const meta = metadata.get(uri) || {};
|
|
objectPropertyUris.add(uri);
|
|
objectProperties.push({
|
|
uri,
|
|
label: meta.label || getLocalName(uri),
|
|
domain: meta.domain,
|
|
range: meta.range,
|
|
});
|
|
}
|
|
|
|
// Build datatype properties list
|
|
const datatypeProperties: OntologyProperty[] = [];
|
|
const datatypePropertyUris = new Set<string>();
|
|
for (const triple of datatypePropertyTriples.triples || []) {
|
|
const uri = getTermValue(triple.s);
|
|
const meta = metadata.get(uri) || {};
|
|
datatypePropertyUris.add(uri);
|
|
datatypeProperties.push({
|
|
uri,
|
|
label: meta.label || getLocalName(uri),
|
|
domain: meta.domain,
|
|
range: meta.range,
|
|
});
|
|
}
|
|
|
|
return {
|
|
classes,
|
|
objectProperties,
|
|
datatypeProperties,
|
|
objectPropertyUris,
|
|
datatypePropertyUris,
|
|
};
|
|
}, [
|
|
isLoading,
|
|
classTriples.triples,
|
|
objectPropertyTriples.triples,
|
|
datatypePropertyTriples.triples,
|
|
allTriples.triples,
|
|
]);
|
|
|
|
return {
|
|
schema,
|
|
isLoading,
|
|
isError,
|
|
error,
|
|
};
|
|
}
|