changeset 82:43e016fa302e

client now works again, reads graph events
author drewp@bigasterisk.com
date Wed, 17 Nov 2021 15:37:45 -0800
parents 099b62d6d0b3
children b973d7f95fdf
files src/streamed_graph_client.ts
diffstat 1 files changed, 99 insertions(+), 100 deletions(-) [+]
line wrap: on
line diff
--- a/src/streamed_graph_client.ts	Wed Nov 17 15:36:41 2021 -0800
+++ b/src/streamed_graph_client.ts	Wed Nov 17 15:37:45 2021 -0800
@@ -1,18 +1,15 @@
-// // from /my/site/homepage/www/rdf/streamed-graph.js
-
-// import { eachJsonLdQuad } from "./json_ld_quads";
-// import { N3Store } from "n3";
+import { eachJsonLdQuad } from "./json_ld_quads";
 import { Store } from "n3";
 
 export class StreamedGraphClient {
-//   // holds a n3 Store, which is synced to a server-side
-//   // store that sends patches over SSE
+  // holds a n3 Store, which is synced to a server-side
+  // store that sends patches over SSE
 
-  onStatus: (msg: string) => void = function(m){};
-  onGraphChanged: () => void = function(){};
+  onStatus: (msg: string) => void = function (m) {};
+  onGraphChanged: () => void = function () {};
   store: Store;
-//   _deletedCount: number = 0;
-//   events!: EventSource;
+  _deletedCount: number = 0;
+  events!: EventSource;
   constructor(
     eventsUrl: string,
     onGraphChanged: () => void,
@@ -27,117 +24,119 @@
 
     this.store = new Store();
 
-//     //     //             Object.keys(prefixes).forEach((prefix) => {
-//     //     //                 this.store.setPrefix(prefix, prefixes[prefix]);
-//     //     //             });
+    // Object.keys(prefixes).forEach((prefix) => {
+    //     this.store.setPrefix(prefix, prefixes[prefix]);
+    // });
 
     this.connect(eventsUrl);
-//     this.reconnectOnWake();
+    this.reconnectOnWake();
 
-//     //     staticGraphUrls.forEach((url) => {
-//     //         fetch(url).then((response) => response.text())
-//     //             .then((body) => {
-//     //                 // parse with n3, add to output
-//     //             });
-//     //     });
+    //     staticGraphUrls.forEach((url) => {
+    //         fetch(url).then((response) => response.text())
+    //             .then((body) => {
+    //                 // parse with n3, add to output
+    //             });
+    //     });
   }
 
-//   _vacuum() {
-//     // workaround for the growing _ids map
-//     this.store = new Store(this.store.getQuads(null, null, null, null));
-//   }
+  _vacuum() {
+    // workaround for the growing _ids map
+    this.store = new Store(this.store.getQuads(null, null, null, null));
+  }
 
-//   reconnectOnWake() {
-//     // it's not this, which fires on every mouse-in on a browser window, and doesn't seem to work for screen-turned-back-on
-//     //window.addEventListener('focus', function() { this.connect(eventsUrl); }.bind(this));
-//   }
+  reconnectOnWake() {
+    // it's not this, which fires on every mouse-in on a browser window, and doesn't seem to work for screen-turned-back-on
+    //window.addEventListener('focus', function() { this.connect(eventsUrl); }.bind(this));
+  }
 
   connect(eventsUrl: string) {
-//     // need to exit here if this obj has been replaced
+    // need to exit here if this obj has been replaced
 
-//     this.onStatus("start connect...");
-//     this.close();
-//     if (this.events && this.events.readyState != EventSource.CLOSED) {
-//       this.onStatus("zombie");
-//       throw new Error("zombie eventsource");
-//     }
+    this.onStatus("start connect...");
+    this.close();
+    if (this.events && this.events.readyState != EventSource.CLOSED) {
+      this.onStatus("zombie");
+      throw new Error("zombie eventsource");
+    }
 
-//     this.events = new EventSource(eventsUrl);
+    this.events = new EventSource(eventsUrl);
 
-//     this.events.addEventListener("error", ev => {
-//       // todo: this is piling up tons of retries and eventually multiple connections
-//       // this.testEventUrl(eventsUrl);
-//       this.onStatus("connection lost- retrying");
-//       setTimeout(() => {
-//         requestAnimationFrame(() => {
-//           this.connect(eventsUrl);
-//         });
-//       }, 3000);
-//     });
+    this.events.addEventListener("error", (ev) => {
+      // todo: this is piling up tons of retries and eventually multiple connections
+      this.testEventUrl(eventsUrl);
+      this.onStatus("connection lost- retrying");
+      setTimeout(() => {
+        requestAnimationFrame(() => {
+          this.connect(eventsUrl);
+        });
+      }, 3000);
+    });
 
-//     this.events.addEventListener("fullGraph", async ev => {
-//       this.onStatus("sync- full graph update");
-//       await this.replaceFullGraph((ev as MessageEvent).data);
-//       this.onStatus(`synced ${this.store.size}`);
-//       this.onGraphChanged();
-//     });
+    this.events.addEventListener("fullGraph", async (ev) => {
+      this.onStatus("sync- full graph update");
+      await this.replaceFullGraph((ev as MessageEvent).data);
+      this.onStatus(`synced ${this.store.size}`);
+      this.onGraphChanged();
+    });
 
-//     this.events.addEventListener("patch", async ev => {
-//       this.onStatus("sync- updating");
-//       await this.patchGraph((ev as MessageEvent).data);
-//       this.onStatus(`synced ${this.store.size}`);
-//       this.onGraphChanged();
-//     });
+    this.events.addEventListener("patch", async (ev) => {
+      this.onStatus("sync- updating");
+      await this.patchGraph((ev as MessageEvent).data);
+      window.setTimeout(() => {
+        this.onStatus(`synced ${this.store.size}`);
+      }, 60);
+      this.onGraphChanged();
+    });
     this.onStatus("connecting...");
   }
 
-//   // these need some locks
-//   async replaceFullGraph(jsonLdText: string) {
-//     this.store = new Store();
-//     await eachJsonLdQuad(
-//       JSON.parse(jsonLdText),
-//       this.store.addQuad.bind(this.store)
-//     );
-//   }
+  // these need some locks
+  async replaceFullGraph(jsonLdText: string) {
+    this.store = new Store();
+    await eachJsonLdQuad(
+      JSON.parse(jsonLdText),
+      this.store.addQuad.bind(this.store)
+    );
+  }
 
-//   async patchGraph(patchJson: string) {
-//     var patch = JSON.parse(patchJson).patch;
+  async patchGraph(patchJson: string) {
+    var patch = JSON.parse(patchJson).patch;
 
-//     await eachJsonLdQuad(patch.deletes, quad => {
-//       this.store.removeQuad(quad);
-//       this._deletedCount++;
-//     });
-//     await eachJsonLdQuad(patch.adds, this.store.addQuad.bind(this.store));
+    await eachJsonLdQuad(patch.deletes, (quad) => {
+      this.store.removeQuad(quad);
+      this._deletedCount++;
+    });
+    await eachJsonLdQuad(patch.adds, this.store.addQuad.bind(this.store));
 
-//     if (this._deletedCount > 100) {
-//       this._vacuum();
-//       this._deletedCount = 0;
-//     }
-//   }
+    if (this._deletedCount > 100) {
+      this._vacuum();
+      this._deletedCount = 0;
+    }
+  }
 
   close() {
-//     if (this.events) {
-//       this.events.close();
-//     }
+    if (this.events) {
+      this.events.close();
+    }
   }
 
-//   async testEventUrl(eventsUrl: string): Promise<void> {
-//     return new Promise<void>((resolve, reject) => {
-//       this.onStatus("testing connection");
-//       fetch(eventsUrl, {
-//         method: "HEAD",
-//         credentials: "include"
-//       })
-//         .then(value => {
-//           if (value.status == 403) {
-//             reject();
-//             return;
-//           }
-//           resolve();
-//         })
-//         .catch(err => {
-//           reject();
-//         });
-//     });
-  // }
+  async testEventUrl(eventsUrl: string): Promise<void> {
+    return new Promise<void>((resolve, reject) => {
+      this.onStatus("testing connection");
+      fetch(eventsUrl, {
+        method: "HEAD",
+        credentials: "include",
+      })
+        .then((value) => {
+          if (value.status == 403) {
+            reject();
+            return;
+          }
+          resolve();
+        })
+        .catch((err) => {
+          reject();
+        });
+    });
+  }
 }