# HG changeset patch # User drewp@bigasterisk.com # Date 1642054513 28800 # Node ID 47d3b5a5bd5e8e5ca305021ee99408115c876c4f # Parent a5f53d397526cdb63cf10874b89ab1195791ba05 refactor diff -r a5f53d397526 -r 47d3b5a5bd5e src/fetchAndParse.ts --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/fetchAndParse.ts Wed Jan 12 22:15:13 2022 -0800 @@ -0,0 +1,21 @@ +import { Store, Parser } from "n3"; + +export async function fetchAndParse(url: string): Promise { + const store = new Store(); + const res = await fetch(url); + const body = await res.text(); + const parser = new Parser({ format: "N3" }); + await new Promise((done, rej) => { + parser.parse(body, (err, quad, prefixes) => { + if (err) { + throw err; + } + if (quad) { + store.addQuad(quad); + } else { + done(null); + } + }); + }); + return store; +} diff -r a5f53d397526 -r 47d3b5a5bd5e src/namespaces.ts --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/namespaces.ts Wed Jan 12 22:15:13 2022 -0800 @@ -0,0 +1,5 @@ +import { Util } from "n3"; + +export const RDFS = Util.prefix("http://www.w3.org/2000/01/rdf-schema#"); +export const RDF = Util.prefix("http://www.w3.org/1999/02/22-rdf-syntax-ns#"); +export const EX = Util.prefix("http://example.com/"); diff -r a5f53d397526 -r 47d3b5a5bd5e src/rdf_value.ts --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/rdf_value.ts Wed Jan 12 22:15:13 2022 -0800 @@ -0,0 +1,46 @@ +import { Store, Term, NamedNode } from "n3"; +import { RDFS } from "./namespaces"; + +function _singleValue(g: Store, s: Term, p: Term): Term { + const quads = g.getQuads(s, p, null, null); + const objs = new Set(quads.map((q) => q.object)); + if (objs.size == 0) { + throw new Error("no value for " + s.value + " " + p.value); + } else if (objs.size == 1) { + const obj = objs.values().next().value; + return obj as Term; + } else { + throw new Error("too many different values: " + JSON.stringify(quads)); + } +} + +export function stringValue(g: Store, s: Term, p: Term): string { + const ret = _singleValue(g, s, p); + if (ret.termType != "Literal") { + throw new Error(`ret=${ret}`); + } + return ret.value as string; +} + +export function uriValue(g: Store, s: Term, p: Term): NamedNode { + const ret = _singleValue(g, s, p); + if (ret.termType != "NamedNode") { + throw new Error(`ret=${ret}`); + } + + return ret; +} + +export function labelOrTail(g: Store, uri: NamedNode): string { + let ret: string; + try { + ret = stringValue(g, uri, RDFS("label")); + } catch (e) { + const words = uri.value.split("/"); + ret = words[words.length - 1]; + } + if (!ret) { + ret = uri.value; + } + return ret; +} diff -r a5f53d397526 -r 47d3b5a5bd5e src/view_loader.ts --- a/src/view_loader.ts Wed Jan 12 22:09:20 2022 -0800 +++ b/src/view_loader.ts Wed Jan 12 22:15:13 2022 -0800 @@ -1,76 +1,10 @@ // Load requested view and provide access to it -import { Store, Parser, Term, NamedNode, DataFactory, Util } from "n3"; +import { Store, NamedNode, DataFactory } from "n3"; +import { fetchAndParse } from "./fetchAndParse"; +import { RDF, EX } from "./namespaces"; +import { labelOrTail, uriValue } from "./rdf_value"; const Uri = DataFactory.namedNode; -const RDFS = Util.prefix("http://www.w3.org/2000/01/rdf-schema#"); -const RDF = Util.prefix("http://www.w3.org/1999/02/22-rdf-syntax-ns#"); -const EX = Util.prefix("http://example.com/"); - -async function fetchAndParse(url: string): Promise { - const store = new Store(); - const res = await fetch(url); - const body = await res.text(); - const parser = new Parser({ format: "N3" }); - await new Promise((done, rej) => { - parser.parse(body, (err, quad, prefixes) => { - if (err) { - throw err; - } - if (quad) { - store.addQuad(quad); - } else { - done(null); - } - }); - }); - return store; -} -function _singleValue(g: Store, s: Term, p: Term): Term { - const quads = g.getQuads(s, p, null, null); - const objs = new Set(quads.map((q) => q.object)); - if (objs.size == 0) { - throw new Error("no value for " + s.value + " " + p.value); - } else if (objs.size == 1) { - const obj = objs.values().next().value; - return obj as Term; - } else { - throw new Error("too many different values: " + JSON.stringify(quads)); - } -} - -function stringValue(g: Store, s: Term, p: Term): string { - const ret = _singleValue(g, s, p); - if (ret.termType != "Literal") { - throw new Error(`ret=${ret}`); - } - return ret.value as string; -} - -function uriValue(g: Store, s: Term, p: Term): NamedNode { - const ret = _singleValue(g, s, p); - if (ret.termType != "NamedNode") { - throw new Error(`ret=${ret}`); - } - - return ret; -} - -function labelOrTail(g: Store, uri: NamedNode): string { - let ret: string; - try { - ret = stringValue(g, uri, RDFS("label")); - } catch (e) { - const words = uri.value.split("/"); - ret = words[words.length - 1]; - } - if (!ret) { - ret = uri.value; - } - return ret; -} -function objects(g: Store, subj: NamedNode, pred: NamedNode): Term[] { - return g.getObjects(subj, pred, null); -} function firstElem(seq: Iterable): E { for (let e of seq) { return e; @@ -82,6 +16,7 @@ graph: Store; ready: Promise; viewRoot!: NamedNode; + constructor(public url: string | "") { (window as any).v = this; //debug this.graph = new Store(); @@ -101,9 +36,11 @@ ) as NamedNode; }); } + label() { return labelOrTail(this.graph, Uri(this.url)); } + // filtered+ordered list of types to show at the top level typesToShow(typesPresent: NamedNode[]): NamedNode[] { const ret: NamedNode[] = [];