testLongTextsAreKeptCompressed

tcmts.store.test.testLongTextsAreKeptCompressed · #mjr5nhvw · term

Long texts are kept compressed, short ones as written; compact compresses those a tcm from before kept as written, and what's read is the same throughout.

import { IR_VERSION } from "#codebase/tcmts/core/hash";
import { PACK_FROM, Store } from "#codebase/tcmts/store";
import { a, b, stored } from "#codebase/tcmts/store/test/history";
import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";

export const testLongTextsAreKeptCompressed = () => {
  const long = JSON.stringify(["Code", "i".repeat(PACK_FROM)]);
  const file = path.join(fs.mkdtempSync(path.join(os.tmpdir(), "tcm store ")), "codebase.sqlite");
  const s = new Store(file);
  s.putDefs([{ ...stored(a, "const f = 1"), ir: long }, stored(b, "const g = 2")], "5", IR_VERSION);
  s.addName("f", a, "term", "add");
  s.endBatch();
  const kinds = () =>
    Object.fromEntries(
      (
        s.db
          .prepare("SELECT hash, typeof(ir) AS ir, typeof(source_text) AS source FROM definitions")
          .all() as {
          hash: string;
          ir: string;
          source: string;
        }[]
      ).map((r) => [r.hash, [r.ir, r.source]]),
    );
  assert.deepEqual(kinds(), { [a]: ["blob", "text"], [b]: ["text", "text"] });
  const read = () => ({ f: s.getDef(a), g: s.getDef(b), names: s.names() });
  const before = read();

  // as a tcm from before wrote it
  s.db.prepare("UPDATE definitions SET ir = ? WHERE hash = ?").run(long, a);
  assert.deepEqual(kinds()[a], ["text", "text"]);
  const r = s.compact();
  assert.equal(r.packed, 1);
  assert.deepEqual(kinds(), { [a]: ["blob", "text"], [b]: ["text", "text"] });
  assert.ok(r.after <= r.before, `${r.after} <= ${r.before}`);
  assert.equal(s.compact().packed, 0, "nothing left to compress");
  s.close();

  const again = new Store(file);
  assert.deepEqual({ f: again.getDef(a), g: again.getDef(b), names: again.names() }, before);
  again.close();
}

uses