Files @ ad7ab7027907
Branch filter:

Location: light9/light9/web/patch.ts

drewp@bigasterisk.com
clean up non-elements; get the lit elements at least to work with autoformat
import debug from "debug";
import * as async from "async";
import { Writer, Parser, Quad, NamedNode } from "n3";
const log = debug("patch");

export interface Patch {
  dels: Quad[];
  adds: Quad[];
  _allPredsCache?: Set<string>;
  _allSubjsCache?: Set<string>;
}

interface SyncgraphPatchMessage {
  patch: { adds: string; deletes: string };
}

export function patchSizeSummary(patch: Patch) {
  return "-" + patch.dels.length + " +" + patch.adds.length;
}

export function parseJsonPatch(input: SyncgraphPatchMessage, cb: (p: Patch) => void) {
  // note response cb doesn't have an error arg.
  const patch: Patch = { dels: [], adds: [] };

  const parseAdds = (cb: () => any) => {
    const parser = new Parser();
    return parser.parse(input.patch.adds, (error: any, quad: Quad, prefixes: any) => {
      if (quad) {
        return patch.adds.push(quad);
      } else {
        return cb();
      }
    });
  };
  const parseDels = (cb: () => any) => {
    const parser = new Parser();
    return parser.parse(input.patch.deletes, (error: any, quad: any, prefixes: any) => {
      if (quad) {
        return patch.dels.push(quad);
      } else {
        return cb();
      }
    });
  };

  return async.parallel([parseAdds, parseDels], (err: any) => cb(patch));
}

export function toJsonPatch(jsPatch: Patch, cb: { (json: any): any; (arg0: any): any }) {
  const out: SyncgraphPatchMessage = { patch: { adds: "", deletes: "" } };

  const writeDels = function (cb: () => any) {
    const writer = new Writer({ format: "N-Quads" });
    writer.addQuads(jsPatch.dels);
    return writer.end(function (err: any, result: string) {
      out.patch.deletes = result;
      return cb();
    });
  };

  const writeAdds = function (cb: () => any) {
    const writer = new Writer({ format: "N-Quads" });
    writer.addQuads(jsPatch.adds);
    return writer.end(function (err: any, result: string) {
      out.patch.adds = result;
      return cb();
    });
  };

  return async.parallel([writeDels, writeAdds], (err: any) => cb(JSON.stringify(out)));
}

export function patchContainsPreds(patch: Patch, preds: NamedNode[]): boolean {
  if (patch._allPredsCache === undefined) {
    patch._allPredsCache = new Set();
    for (let qq of [patch.adds, patch.dels]) {
      for (let q of Array.from(qq)) {
        patch._allPredsCache.add(q.predicate.value);
      }
    }
  }

  for (let p of Array.from(preds)) {
    if (patch._allPredsCache.has(p.value)) {
      return true;
    }
  }
  return false;
}

export function allPatchSubjs(patch: Patch): Set<string> {
  // returns subjs as Set of strings
  const out = new Set();
  if (patch._allSubjsCache === undefined) {
    patch._allSubjsCache = new Set();
    for (let qq of [patch.adds, patch.dels]) {
      for (let q of Array.from(qq)) {
        patch._allSubjsCache.add(q.subject.value);
      }
    }
  }

  return patch._allSubjsCache;
}