alinea
Version:
[](https://npmjs.org/package/alinea) [](https://packagephobia.com/result?p=alinea)
102 lines (100 loc) • 2.78 kB
JavaScript
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
};