view src/layout/rdf_value.ts @ 143:5adf79d4a9f4

release v0.11.0
author drewp@bigasterisk.com
date Mon, 08 May 2023 13:29:48 -0700
parents 4b33a479dc2f
children
line wrap: on
line source

import { NamedNode, Store, Term } 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;
}

export function uniqueSortedTerms<T extends NamedNode | Term>(
  terms: Iterable<T>
): T[] {
  const uniques: T[] = [];
  const seen = new Set();
  for (let o of terms) {
    if (!seen.has(o.id)) {
      seen.add(o.id);
      uniques.push(o);
    }
  }
  uniques.sort((a, b) => {
    return a.id.localeCompare(b.id);
  });
  return uniques;
}

// A default dict of Term[] with (NamedNode,NamedNode) pairs as keys.
//
// Immutable.Map<Immutable.Record<Uri,Uri>, Immutable.Set<Term>>() didn't seem to work.
export class UriPairMap {
  _d = new Map<string, Term[]>();

  _key(k1: NamedNode, k2: NamedNode): string {
    return k1.id + "|" + k2.id;
  }

  add(k1: NamedNode, k2: NamedNode, v: Term) {
    const key = this._key(k1, k2);
    let cur = this._d.get(key);
    if (cur === undefined) {
      cur = [];
      this._d.set(key, cur);
    }
    cur.push(v);
  }

  get(k1: NamedNode, k2: NamedNode): Term[] {
    const key = this._key(k1, k2);
    const v = this._d.get(key);
    if (v === undefined) {
      return [];
    }
    return v;
  }
}