Changeset - 33f65e2d0e59
[Not reviewed]
default
1 4 0
drewp@bigasterisk.com - 3 years ago 2022-05-24 07:00:38
drewp@bigasterisk.com
who needs a single emitter of all graph change events that anyone on the page can find?
if it's you, revert this change
5 files changed with 12 insertions and 77 deletions:
0 comments (0 inline, 0 general)
light9/collector/web/Light9CollectorUi.ts
Show inline comments
 
import debug from "debug";
 
import { html, LitElement } from "lit";
 
import { customElement, property, state } from "lit/decorators.js";
 
import ReconnectingWebSocket from "reconnectingwebsocket";
 
import { customElement, property } from "lit/decorators.js";
 
import { NamedNode } from "n3";
 
import { sortBy, uniq } from "underscore";
 
import { Patch } from "../../web/patch";
 
import { getTopGraph } from "../../web/RdfdbSyncedGraph";
 
import { SyncedGraph } from "../../web/SyncedGraph";
 
import { GraphAwarePage } from "../../web/GraphAwarePage";
 
import { getTopGraph, GraphChangedEvent } from "../../web/RdfdbSyncedGraph";
 
import { NamedNode } from "n3";
 
import { Patch } from "../../web/patch";
 
import { linkHorizontal } from "d3";
 

	
 
export { Light9CollectorDevice } from "../../web/collector/Light9CollectorDevice";
 
export { RdfdbSyncedGraph } from "../../web/RdfdbSyncedGraph";
 
export { Light9CollectorDevice } from "../../web/collector/Light9CollectorDevice";
 

	
 
debug.enable("*");
 
const log = debug("collector");
 

	
 
@customElement("light9-collector-ui")
 
export class Light9CollectorUi extends GraphAwarePage {
 
export class Light9CollectorUi extends LitElement {
 
  graph!: SyncedGraph;
 
  render() {
 
    return html`${super.render()}
 
    return html`<rdfdb-synced-graph></rdfdb-synced-graph>
 
      <h1>Collector <a href="metrics">[metrics]</a></h1>
 

	
 
      <h2>Devices</h2>
 
      <light9-collector-device-list></light9-collector-device-list> `;
 
  }
 
      <div style="column-width: 11em">${this.devices.map((d) => html`<light9-collector-device uri="${d.value}"></light9-collector-device>`)}</div> `;
 
}
 

	
 
@customElement("light9-collector-device-list")
 
export class Light9CollectorDeviceList extends LitElement {
 
  graph!: SyncedGraph;
 
  @property() devices: NamedNode[] = [];
 
  
 
  render() {
 
    return html`
 
      <h2>Devices</h2>
 
      <div style="column-width: 11em">${this.devices.map((d) => html`<light9-collector-device uri="${d.value}"></light9-collector-device>`)}</div>
 
    `;
 
  }
 
  
 
  constructor() {
 
    super();
 
    getTopGraph().then((g) => {
 
      this.graph = g;
 
      this.graph.runHandler(this.findDevices.bind(this), "findDevices");
 
    });
 
  }
 
  
 
  findDevices(patch?: Patch) {
 
    const U = this.graph.U();
 
    
 
    this.devices = [];
light9/web/GraphAwarePage.ts
Show inline comments
 
deleted file
light9/web/RdfdbSyncedGraph.ts
Show inline comments
 
import debug from "debug";
 
import { html, LitElement, css } from "lit";
 
import { customElement, property } from "lit/decorators.js";
 
import { Patch } from "./patch";
 
import { SyncedGraph } from "./SyncedGraph";
 

	
 
const log = debug("syncedgraph-el");
 

	
 
// consider https://vitaly-t.github.io/sub-events/ for this stuff
 
export interface GraphChangedDetail {
 
  graph: SyncedGraph;
 
  patch: Patch;
 
}
 

	
 
export class GraphChangedEvent extends CustomEvent<GraphChangedDetail> {
 
  constructor(type: string, opts: { detail: GraphChangedDetail; bubbles: boolean; composed: boolean }) {
 
    super(type, opts);
 
  }
 
}
 

	
 
let setTopGraph: (sg: SyncedGraph) => void;
 
(window as any).topSyncedGraph = new Promise<SyncedGraph>((res, rej) => {
 
  setTopGraph = res;
 
});
 

	
 
// Contains a SyncedGraph,
 
// displays a little status box,
 
// and emits 'changed' events with the graph and latest patch when it changes
 
@customElement("rdfdb-synced-graph")
 
export class RdfdbSyncedGraph extends LitElement {
 
  @property() graph: SyncedGraph;
 
@@ -57,32 +46,22 @@ export class RdfdbSyncedGraph extends Li
 
      this.testGraph ? null : "/rdfdb/api/syncedGraph",
 
      {
 
        "": "http://light9.bigasterisk.com/",
 
        dev: "http://light9.bigasterisk.com/device/",
 
        rdf: "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
 
        rdfs: "http://www.w3.org/2000/01/rdf-schema#",
 
        xsd: "http://www.w3.org/2001/XMLSchema#",
 
      },
 
      (s: string) => {
 
        this.status = s;
 
      },
 
      this.onClear.bind(this),
 
      this.onGraphChanged.bind(this)
 
    );
 
    setTopGraph(this.graph);
 
  }
 

	
 
  private onGraphChanged(graph: SyncedGraph, patch: Patch) {
 
    this.dispatchEvent(
 
      new GraphChangedEvent("changed", {
 
        detail: { graph, patch },
 
        bubbles: true,
 
        composed: true,
 
      })
 
    );
 
  }
 
}
 

	
 
export async function getTopGraph(): Promise<SyncedGraph> {
 
  const s = (window as any).topSyncedGraph;
 
  return await s;
 
}
light9/web/SyncedGraph.ts
Show inline comments
 
@@ -24,26 +24,25 @@ export class SyncedGraph {
 
  // later.
 
  //
 
  // Note that _applyPatch is the only method to write to the graph, so
 
  // it can fire subscriptions.
 

	
 
  constructor(
 
    // url is the /syncedGraph path of an rdfdb server.
 
    public url: any,
 
    // prefixes can be used in Uri(curie) calls.
 
    public prefixes: { [short: string]: string },
 
    private setStatus: any,
 
    // called if we clear the graph
 
    private clearCb: any,
 
    private onGraphChanged: (graph: SyncedGraph, newPatch: Patch)=>void
 
    private clearCb: any
 
  ) {
 
    this.graph = new N3.Store();
 
    this._autoDeps = new AutoDependencies();
 
    this.clearGraph();
 

	
 
    this._client = new RdfDbClient(this.url, this._clearGraphOnNewConnection.bind(this), this._applyPatch.bind(this), this.setStatus);
 
  }
 

	
 
  clearGraph() {
 
    // just deletes the statements; watchers are unaffected.
 
    this.cachedFloatValues = new Map(); // s + '|' + p -> number
 
    this.cachedUriValues = new Map(); // s + '|' + p -> Uri
 
@@ -176,25 +175,24 @@ export class SyncedGraph {
 
    this.cachedFloatValues.clear();
 
    this.cachedUriValues.clear();
 
    for (let quad of Array.from(patch.dels)) {
 
      //log("remove #{JSON.stringify(quad)}")
 
      const did = this.graph.removeQuad(quad);
 
    }
 
    //log("removed: #{did}")
 
    for (let quad of Array.from(patch.adds)) {
 
      this.graph.addQuad(quad);
 
    }
 
    log("applied patch locally", patchSizeSummary(patch));
 
    this._autoDeps.graphChanged(patch);
 
    this.onGraphChanged(this, patch);
 
  }
 

	
 
  getObjectPatch(s: N3.NamedNode, p: N3.NamedNode, newObject: N3.Quad_Object, g: N3.NamedNode): Patch {
 
    // make a patch which removes existing values for (s,p,*,c) and
 
    // adds (s,p,newObject,c). Values in other graphs are not affected.
 
    const existing = this.graph.getQuads(s, p, null, g);
 
    return {
 
      dels: existing,
 
      adds: [this.Quad(s, p, newObject, g)],
 
    };
 
  }
 

	
light9/web/collector/Light9CollectorDevice.ts
Show inline comments
 
import debug from "debug";
 
import { css, html, LitElement } from "lit";
 
import { customElement, property } from "lit/decorators.js";
 
import { NamedNode } from "n3";
 
import { GraphChangedEvent } from "../RdfdbSyncedGraph";
 
export {ResourceDisplay} from "../ResourceDisplay"
 
export { ResourceDisplay } from "../ResourceDisplay";
 

	
 
debug.enable("*");
 
const log = debug("device-el");
 

	
 
@customElement("light9-collector-device")
 
export class Light9CollectorDevice extends LitElement {
 
  static styles = [
 
    css`
 
      :host {
 
        display: block;
 
        break-inside: avoid-column;
 
        font-size: 80%;
 
      }
 
@@ -57,28 +57,24 @@ export class Light9CollectorDevice exten
 
      </table>
 
    `;
 
  }
 
  @property({
 
    // todo don't rebuild uri; pass it right
 
    converter: (s: string | null) => new NamedNode(s || ""),
 
  })
 
  uri: NamedNode = new NamedNode("");
 
  @property() attrs: Array<{ attr: string; valClass: string; val: string; chan: string }> = [];
 

	
 
  constructor() {
 
    super();
 
    // addGraphChangeListener(this.onGraphChanged.bind(this));
 
  }
 
  onChanged(ev: GraphChangedEvent) {
 
    log("patch from server [5]");
 
  }
 
  //  observers: [
 
  //    "initUpdates(updates)",
 
  //  ],
 
  // initUpdates(updates) {
 
  //   updates.addListener(function (msg) {
 
  //     if (msg.outputAttrsSet && msg.outputAttrsSet.dev == this.uri.value) {
 
  //       this.set("attrs", msg.outputAttrsSet.attrs);
 
  //       this.attrs.forEach(function (row) {
 
  //         row.valClass = row.val == 255 ? "full" : row.val ? "nonzero" : "";
 
  //       });
 
  //     }
0 comments (0 inline, 0 general)