UNPKG

alinea

Version:

[![npm](https://img.shields.io/npm/v/alinea.svg)](https://npmjs.org/package/alinea) [![install size](https://packagephobia.com/badge?p=alinea)](https://packagephobia.com/result?p=alinea)

102 lines (100 loc) 2.78 kB
import { atomFamily } from "../../chunks/chunk-ZHH24SIG.js"; import { atom } from "../../chunks/chunk-OBOPLPUQ.js"; import { Doc, applyUpdateV2, encodeStateAsUpdateV2, encodeStateVectorFromUpdateV2 } from "../../chunks/chunk-OYP4EJOA.js"; import "../../chunks/chunk-O6EXLFU2.js"; import "../../chunks/chunk-U5RRZUYZ.js"; // src/dashboard/atoms/Edits.ts import { ROOT_KEY, Type } from "alinea/core"; import { yAtom } from "./YAtom.js"; var Edits = class _Edits { constructor(entryId) { this.entryId = entryId; } /** The mutable doc that we are editing */ doc = new Doc(); /** The state vector of the source doc */ sourceVector; sourceUpdate; /** The root map containing field data */ root = this.doc.getMap(ROOT_KEY); /** Did we make any local changes? */ hasChanges = createChangesAtom(this.root); /** Clear local changes, reset to source */ resetChanges = atom(null, (get, set) => { set(this.hasChanges, false); const copy = new _Edits(this.entryId); if (this.sourceUpdate) copy.applyRemoteUpdate(this.sourceUpdate); set(entryEditsAtoms(this.entryId), copy); }); /** Whether we have a draft loaded */ isLoading = yAtom(this.root, () => { return !this.hasData(); }); yUpdate = yAtom(this.root, () => { return this.getLocalUpdate(); }); hasData() { return !this.root.keys().next().done; } /** Apply updates from the source */ applyRemoteUpdate(update) { this.sourceUpdate = update; this.applyLocalUpdate(update); this.sourceVector = encodeStateVectorFromUpdateV2(update); } /** Apply local updates */ applyLocalUpdate(update) { applyUpdateV2(this.doc, update, "self"); } /** A Y.js update that contains our own edits, base64 encoded */ getLocalUpdate() { return encodeStateAsUpdateV2(this.doc, this.sourceVector); } /** The source doc */ getRemoteUpdate() { return encodeStateAsUpdateV2(this.doc); } /** Update entry field data */ applyEntryData(type, entryData) { const clientID = this.doc.clientID; this.doc.clientID = 1; this.doc.transact(() => { Type.shape(type).applyY(entryData, this.doc, ROOT_KEY); }, "self"); this.doc.clientID = clientID; } /** The field data */ getEntryData(type) { return Type.shape(type).fromY(this.root); } }; function createChangesAtom(yMap) { const hasChanges = atom(false); hasChanges.onMount = (setAtom) => { const listener = (events, tx) => { if (tx.origin === "self") return; setAtom(true); }; yMap.observeDeep(listener); return () => yMap.unobserveDeep(listener); }; return hasChanges; } var entryEditsAtoms = atomFamily((entryId) => { return atom(new Edits(entryId)); }); export { Edits, entryEditsAtoms };