changeset 2268:094e6b84b291

logging and refactor
author drewp@bigasterisk.com
date Mon, 29 May 2023 13:20:46 -0700
parents 7796bc3e46b1
children cd4a9eeeb9e6
files light9/web/AutoDependencies.ts light9/web/RdfdbSyncedGraph.ts light9/web/SyncedGraph.ts light9/web/patch.ts
diffstat 4 files changed, 52 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/light9/web/AutoDependencies.ts	Mon May 29 11:50:48 2023 -0700
+++ b/light9/web/AutoDependencies.ts	Mon May 29 13:20:46 2023 -0700
@@ -33,6 +33,8 @@
     // patterns). Top node is not a handler.
     this.handlers = new Handler(null, "root");
     this.handlerStack = [this.handlers]; // currently running
+    log("window.ad");
+    (window as any).ad = this;
   }
 
   runHandler(func: HandlerFunc, label: string) {
@@ -53,9 +55,9 @@
     // graph is initially loaded, which is a waste. Try deferring it if we
     // haven't gotten the graph yet.
     this._rerunHandler(h, /*patch=*/ undefined);
+    log(`new handler ${label} ran first time and requested ${h.patterns.length} pats`);
   }
-  //console.timeEnd("handler #{label}")
-  //@_logHandlerTree()
+
   _rerunHandler(handler: Handler, patch?: Patch) {
     handler.patterns = [];
     this.handlerStack.push(handler);
@@ -65,7 +67,7 @@
       }
       handler.func(patch);
     } catch (e) {
-      log("error running handler: ", e);
+      this.graphError.emit(String(e));
     } finally {
       // assuming here it didn't get to do all its queries, we could
       // add a *,*,*,* handler to call for sure the next time?
@@ -76,15 +78,24 @@
   // handler might have no watches, in which case we could forget about it
   logHandlerTree() {
     log("handler tree:");
-    var prn = function (h: Handler, depth: number) {
-      let indent = "";
-      for (let i = 0; i < depth; i++) {
-        indent += "  ";
+    const shorten = (x: Term | null) => {
+      if (x === null) {
+        return "null";
+      }
+      if (!Util.isNamedNode(x)) {
+        return x.value;
       }
-      log(`${indent} \"${h.label}\" ${h.patterns.length} pats`);
-      Array.from(h.innerHandlers).map((c: any) => prn(c, depth + 1));
+      return this.graph.shorten(x as NamedNode);
     };
-    prn(this.handlers, 0);
+
+    var prn = (h: Handler, indent: string) => {
+      log(`${indent} 🤝 handler "${h.label}" ${h.patterns.length} pats`);
+      for (let pat of h.patterns) {
+        log(`${indent}   ⣝ s=${shorten(pat.subject)} p=${shorten(pat.predicate)} o=${shorten(pat.object)}`);
+      }
+      Array.from(h.innerHandlers).map((c: any) => prn(c, indent + "    "));
+    };
+    prn(this.handlers, "");
   }
 
   _handlerIsAffected(child: Handler, patchSubjs: Set<string>) {
--- a/light9/web/RdfdbSyncedGraph.ts	Mon May 29 11:50:48 2023 -0700
+++ b/light9/web/RdfdbSyncedGraph.ts	Mon May 29 13:20:46 2023 -0700
@@ -1,22 +1,12 @@
 import debug from "debug";
-import { html, LitElement, css } from "lit";
+import { LitElement, css, html } from "lit";
 import { customElement, property } from "lit/decorators.js";
-import { NamedNode } from "n3";
-import { Patch } from "./patch";
 import { SyncedGraph } from "./SyncedGraph";
 
 const log = debug("syncedgraph-el");
 
-// todo: consider if this has anything to contribute:
-// https://github.com/webcomponents-cg/community-protocols/blob/main/proposals/context.md
-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
+// Contains a SyncedGraph. Displays as little status box.
+// Put one element on your page and use getTopGraph everywhere.
 @customElement("rdfdb-synced-graph")
 export class RdfdbSyncedGraph extends LitElement {
   @property() graph: SyncedGraph;
@@ -37,10 +27,6 @@
     return html`graph: ${this.status}`;
   }
 
-  onClear() {
-    console.log("reset");
-  }
-
   constructor() {
     super();
     this.status = "startup";
@@ -52,17 +38,23 @@
       ["xsd", "http://www.w3.org/2001/XMLSchema#"],
     ]);
     this.graph = new SyncedGraph(
-      this.testGraph ? null : "/rdfdb/api/syncedGraph",
+      this.testGraph ? "unused" : "/rdfdb/api/syncedGraph",
       prefixes,
       (s: string) => {
         this.status = s;
-      },
-      this.onClear.bind(this)
+      }
     );
     setTopGraph(this.graph);
   }
 }
 
+// todo: consider if this has anything to contribute:
+// https://github.com/webcomponents-cg/community-protocols/blob/main/proposals/context.md
+let setTopGraph: (sg: SyncedGraph) => void;
+(window as any).topSyncedGraph = new Promise<SyncedGraph>((res, rej) => {
+  setTopGraph = res;
+});
+
 export async function getTopGraph(): Promise<SyncedGraph> {
   const s = (window as any).topSyncedGraph;
   return await s;
--- a/light9/web/SyncedGraph.ts	Mon May 29 11:50:48 2023 -0700
+++ b/light9/web/SyncedGraph.ts	Mon May 29 13:20:46 2023 -0700
@@ -31,8 +31,6 @@
     patchSenderUrl: string,
     // prefixes can be used in Uri(curie) calls. This mapping may grow during loadTrig calls.
     public prefixes: Map<string, string>,
-    // called if we clear the graph
-    private clearCb: any
     private setStatus: (status: string) => void
   ) {
     this.prefixFuncs = this.rebuildPrefixFuncs(prefixes);
@@ -61,9 +59,6 @@
     log("clearGraphOnNewConnection");
     this.clearGraph();
     log("clearGraphOnNewConnection done");
-    if (this.clearCb != null) {
-      return this.clearCb();
-    }
   }
 
   private rebuildPrefixFuncs(prefixes: Map<string, string>) {
@@ -171,6 +166,7 @@
     this.cachedUriValues.clear();
     patch.applyToGraph(this.graph);
     log("applied patch locally", patch.summary());
+    log('dump:\n'+patch.dump());
     this.autoDeps.graphChanged(patch);
   }
 
--- a/light9/web/patch.ts	Mon May 29 11:50:48 2023 -0700
+++ b/light9/web/patch.ts	Mon May 29 13:20:46 2023 -0700
@@ -73,6 +73,24 @@
     return "-" + this.dels.length + " +" + this.adds.length;
   }
 
+  dump(): string {
+    const lines: string[] = [];
+    const s = (term: N3.Term): string => {
+      if (term.termType=='Literal') return term.value;
+      if (term.termType=='NamedNode') return term.value
+        .replace("http://light9.bigasterisk.com/effect/","effect:")
+        .replace("http://light9.bigasterisk.com/",":")
+        .replace("http://www.w3.org/2000/01/rdf-schema#","rdfs:")
+        .replace("http://www.w3.org/1999/02/22-rdf-syntax-ns#", "rdf:")
+      if (term.termType=='BlankNode') return '_:'+term.value;
+      return term.id;
+    };
+    this.dels.forEach((d) => lines.push("- " + s(d.subject) + " " + s(d.predicate) + " " + s(d.object)));
+    this.adds.forEach((d) => lines.push("+ " + s(d.subject) + " " + s(d.predicate) + " " + s(d.object)));
+    lines.sort();
+    return lines.join("\n");
+  }
+
   async toJsonPatch(): Promise<string> {
     return new Promise((res, rej) => {
       const out: SyncgraphPatchMessage = { patch: { adds: "", deletes: "" } };