← Source tree

web_demo/core.js

/* Original internal demo logic. Existing project BSD-3-Clause notice applies. */
(function (root, factory) {
  const api = factory();
  if (typeof module === "object" && module.exports) module.exports = api;
  else root.ReviewDemo = api;
})(globalThis, function () {
  "use strict";
  async function sha256(text) {
    if (!globalThis.crypto?.subtle) throw new Error("Web Crypto unavailable; export stays disabled.");
    const bytes = new TextEncoder().encode(text);
    const hash = await globalThis.crypto.subtle.digest("SHA-256", bytes);
    return Array.from(new Uint8Array(hash), n => n.toString(16).padStart(2, "0")).join("");
  }
  class Session {
    #json; #digest = null; #confirmed = false; #epoch = 0; #hash;
    constructor(report, hash = sha256) {
      const copy = JSON.parse(JSON.stringify(report));
      if (!Array.isArray(copy.rows) || copy.input_rows !== copy.rows.length ||
          copy.output_rows !== copy.rows.length ||
          copy.review_rows !== copy.rows.filter(r => r.needs_review === true).length ||
          copy.rows.some((r, i) => r.row_number !== i + 1 || !r.original ||
            typeof r.original !== "object" || Array.isArray(r.original) ||
            !Array.isArray(r.flags) || typeof r.needs_review !== "boolean")) {
        throw new Error("Invalid demonstration report");
      }
      this.#json = JSON.stringify({
        simulation: "ReviewQueue browser report viewer 0.1",
        limits: "Synthetic, precomputed report only. This report is precomputed; the separate live panel uses a synthetic forest. No authentication, owner approval or submission.",
        review: copy
      }, null, 2);
      this.#hash = hash;
    }
    async review() {
      const epoch = ++this.#epoch;
      this.#confirmed = false;
      this.#digest = null;
      const digest = await this.#hash(this.#json);
      if (epoch !== this.#epoch) throw new Error("Review cancelled; review again.");
      this.#digest = digest;
      return { document: JSON.parse(this.#json), digest, state: "awaiting_demo_confirmation" };
    }
    confirm(digest) {
      if (!this.#digest || digest !== this.#digest) throw new Error("Review and confirm the exact current digest first.");
      this.#confirmed = true;
      return "demo_confirmed";
    }
    export() {
      if (!this.#confirmed) throw new Error("Demo confirmation required; nothing exported.");
      return this.#json; // Exact reviewed bytes; no row/flag removal or rewriting.
    }
    reset() {
      ++this.#epoch;
      this.#digest = null;
      this.#confirmed = false;
      return "unreviewed";
    }
  }
  return { Session, sha256 };
});