import * as Automerge from "@automerge/automerge"; const bytesToBase64 = (value) => { if (typeof Buffer !== "undefined") { return Buffer.from(value).toString("base64"); } let binary = ""; for (const byte of value) { binary += String.fromCharCode(byte); } return btoa(binary); }; const base64ToBytes = (value) => { if (typeof Buffer !== "undefined") { return Buffer.from(value, "base64"); } const binary = atob(value); const bytes = new Uint8Array(binary.length); for (let index = 0; index < binary.length; index += 1) { bytes[index] = binary.charCodeAt(index); } return bytes; }; export const isCaminoCrdtEnvelope = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value) && typeof value.$caminoCrdtType === "string" && typeof value.$caminoCrdtPayload === "string" && (value.$caminoCrdtEncoding === undefined || value.$caminoCrdtEncoding === "base64"); const assertEnvelopeType = (value, type) => { if (value.$caminoCrdtType !== type) { throw new Error(`CRDT type mismatch: expected ${type}, got ${value.$caminoCrdtType}`); } }; export const loadAutomergeFieldDoc = (value, type) => { assertEnvelopeType(value, type); return Automerge.load(base64ToBytes(value.$caminoCrdtPayload)); }; export const saveAutomergeFieldDoc = (doc, type) => ({ $caminoCrdtType: type, $caminoCrdtEncoding: "base64", $caminoCrdtPayload: bytesToBase64(Automerge.save(doc)), }); export const createAutomergeFieldValue = (value, type) => saveAutomergeFieldDoc(Automerge.from({ value }), type); export const isAutomergeFieldDoc = (value) => { if (!value || typeof value !== "object") { return false; } try { Automerge.getHeads(value); return true; } catch { return false; } }; export const encodeAutomergeFieldWrite = (value, type) => { if (isCaminoCrdtEnvelope(value)) { return saveAutomergeFieldDoc(loadAutomergeFieldDoc(value, type), type); } if (isAutomergeFieldDoc(value)) { return saveAutomergeFieldDoc(value, type); } throw new Error("CRDT field writes must use an Automerge document or Camino CRDT envelope"); }; export const normalizeAutomergeFieldValue = (value, type) => encodeAutomergeFieldWrite(value, type); export const materializeAutomergeFieldValue = (value, type) => loadAutomergeFieldDoc(value, type).value; export const mergeAutomergeFieldValues = ({ existing, incoming, type, }) => { const incomingDoc = loadAutomergeFieldDoc(normalizeAutomergeFieldValue(incoming, type), type); const mergedDoc = existing === undefined || existing === null ? incomingDoc : Automerge.merge(loadAutomergeFieldDoc(normalizeAutomergeFieldValue(existing, type), type), incomingDoc); const stored = saveAutomergeFieldDoc(mergedDoc, type); return { stored, materialized: mergedDoc.value, }; }; //# sourceMappingURL=crdt-automerge.js.map