Files @ 4556eebe5d73
Branch filter:

Location: light9/web/rdfdbclient.ts - annotation

drewp@bigasterisk.com
topdir reorgs; let pdm have its src/ dir; separate vite area from light9/
import debug from "debug";
import { parseJsonPatch, Patch } from "./patch";
import { RdfDbChannel } from "./RdfDbChannel";
const log = debug("rdfdbclient");

export class RdfDbClient {
  private channel: RdfDbChannel;
  _patchesToSend: Patch[];
  // Send and receive patches from rdfdb. Primarily used in SyncedGraph.
  //
  // What this should do, and does not yet, is keep the graph
  // 'coasting' over a reconnect, applying only the diffs from the old
  // contents to the new ones once they're in. Then, remove all the
  // clearGraph stuff in graph.coffee that doesn't even work right.
  //
  constructor(
    patchSenderUrl: string,
    private clearGraphOnNewConnection: () => void,
    private applyPatch: (p: Patch) => void,
    setStatus: (status: string) => void
  ) {
    this._patchesToSend = [];
    this.channel = new RdfDbChannel(patchSenderUrl);
    this.channel.statusDisplay.subscribe((st: string) => {
      setStatus(st + `; ${this._patchesToSend.length} pending `);
    });
    this.channel.newConnection.subscribe(() => {
      this.clearGraphOnNewConnection();
    });
    this.channel.serverMessage.subscribe((m) => {
      parseJsonPatch(m.body, (p: Patch) => {
        log('patch from server:', p.dump())
        if (p.isEmpty()) {
          return;
        }
        this.applyPatch(p);
      });
    });
  }

  sendPatch(patch: Patch) {
    log("queue patch to server ", patch.summary());
    this._patchesToSend.push(patch);
    this._continueSending();
  }

  disconnect(why:string) {
    this.channel.disconnect(why);
  }

  async _continueSending() {
    // we could call this less often and coalesce patches together to optimize
    // the dragging cases. See rdfdb 'compactPatches' and 'processInbox'.
    while (this._patchesToSend.length) {
      const patch = this._patchesToSend.splice(0, 1)[0];
      const json = await patch.toJsonPatch();
      const ret = this.channel.sendMessage(json);
      if (!ret) {
        setTimeout(this._continueSending.bind(this), 500);

        // this.disconnect()
        return;
      }
    }
  }
}