Add incremental Automerge field changes
This commit is contained in:
@@ -2,7 +2,10 @@ import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
import * as Automerge from "@automerge/automerge";
|
||||
import {
|
||||
AUTOMERGE_CHANGES_ENCODING,
|
||||
AUTOMERGE_SNAPSHOT_ENCODING,
|
||||
createAutomergeFieldValue,
|
||||
createAutomergeFieldChanges,
|
||||
encodeAutomergeFieldWrite,
|
||||
isAutomergeFieldDoc,
|
||||
loadAutomergeFieldDoc,
|
||||
@@ -17,7 +20,7 @@ test("Automerge CRDT fields explicitly create stored envelopes", () => {
|
||||
const stored = createAutomergeFieldValue({ title: "draft" }, type);
|
||||
|
||||
assert.equal(stored.$caminoCrdtType, type);
|
||||
assert.equal(stored.$caminoCrdtEncoding, "base64");
|
||||
assert.equal(stored.$caminoCrdtEncoding, AUTOMERGE_SNAPSHOT_ENCODING);
|
||||
assert.deepEqual(materializeAutomergeFieldValue(stored, type), {
|
||||
title: "draft",
|
||||
});
|
||||
@@ -72,3 +75,49 @@ test("Automerge CRDT fields merge divergent saved documents", () => {
|
||||
right: true,
|
||||
});
|
||||
});
|
||||
|
||||
test("Automerge CRDT fields encode and apply incremental changes", () => {
|
||||
const stored = createAutomergeFieldValue({ title: "draft" }, type);
|
||||
const base = loadAutomergeFieldDoc(stored, type);
|
||||
const changed = Automerge.change(base, (doc) => {
|
||||
(doc.value as { title: string }).title = "edited";
|
||||
});
|
||||
const update = createAutomergeFieldChanges(base, changed, type);
|
||||
|
||||
assert.equal(update.$caminoCrdtEncoding, AUTOMERGE_CHANGES_ENCODING);
|
||||
assert.ok(update.$caminoCrdtPayload.length < saveAutomergeFieldDoc(changed, type).$caminoCrdtPayload.length);
|
||||
|
||||
const result = mergeAutomergeFieldValues({ existing: stored, incoming: update, type });
|
||||
assert.deepEqual(result.materialized, { title: "edited" });
|
||||
assert.equal(result.stored.$caminoCrdtEncoding, AUTOMERGE_SNAPSHOT_ENCODING);
|
||||
});
|
||||
|
||||
test("Automerge change application is idempotent", () => {
|
||||
const stored = createAutomergeFieldValue({ count: 0 }, type);
|
||||
const base = loadAutomergeFieldDoc(stored, type);
|
||||
const changed = Automerge.change(base, (doc) => {
|
||||
(doc.value as { count: number }).count = 1;
|
||||
});
|
||||
const update = createAutomergeFieldChanges(base, changed, type);
|
||||
|
||||
const once = mergeAutomergeFieldValues({ existing: stored, incoming: update, type });
|
||||
const twice = mergeAutomergeFieldValues({ existing: once.stored, incoming: update, type });
|
||||
assert.deepEqual(twice.materialized, { count: 1 });
|
||||
});
|
||||
|
||||
test("Automerge change batches reject malformed framing", () => {
|
||||
const stored = createAutomergeFieldValue({ count: 0 }, type);
|
||||
assert.throws(
|
||||
() =>
|
||||
mergeAutomergeFieldValues({
|
||||
existing: stored,
|
||||
incoming: {
|
||||
$caminoCrdtType: type,
|
||||
$caminoCrdtEncoding: AUTOMERGE_CHANGES_ENCODING,
|
||||
$caminoCrdtPayload: Buffer.from([0, 0, 0, 1]).toString("base64"),
|
||||
},
|
||||
type,
|
||||
}),
|
||||
/missing change length/,
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user