UNPKG

mute-structs

Version:

NodeJS module providing an implementation of the LogootSplit CRDT algorithm

104 lines (100 loc) 3.75 kB
/* This file is part of MUTE-structs. Copyright (C) 2017 Matthieu Nicolas, Victorien Elvinger This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. */ import { isObject } from "../../data-validation"; import { IdentifierInterval } from "../../identifierinterval"; import { isInt32 } from "../../int32"; import { LogootSOperation } from "../logootsoperation"; const arrayConcat = Array.prototype.concat; class LogootSDelV1 { static fromPlain(o) { if (isObject(o) && Array.isArray(o.lid) && o.lid.length > 0) { let isOk = true; let i = 0; const lid = []; while (isOk && i < o.lid.length) { const idi = IdentifierInterval.fromPlain(o.lid[i]); if (idi !== null) { lid.push(idi); } else { isOk = false; } i++; } if (isOk) { return new LogootSDel(lid, -1); } } return null; } } /** * Represents a LogootSplit delete operation. */ export class LogootSDel extends LogootSOperation { /** * @constructor * @param {IdentifierInterval[]} lid - the list of identifier that localise the deletion in the logoot sequence. * @param {number} author - the author of the operation. */ constructor(lid, author) { console.assert(lid.length > 0, "lid must not be empty"); console.assert(isInt32(author), "author ∈ int32"); super(); this.lid = lid; this.author = author; } static fromPlain(o) { if (isObject(o) && Array.isArray(o.lid) && o.lid.length > 0 && isInt32(o.author)) { let isOk = true; let i = 0; const lid = []; while (isOk && i < o.lid.length) { const idi = IdentifierInterval.fromPlain(o.lid[i]); if (idi !== null) { lid.push(idi); } else { isOk = false; } i++; } if (isOk) { return new LogootSDel(lid, o.author); } } // For backward compatibility // Allow to replay and update previous log of operations return LogootSDelV1.fromPlain(o); } equals(aOther) { return (this.lid.length === aOther.lid.length && this.lid.every((idInterval, index) => { const otherIdInterval = aOther.lid[index]; return idInterval.equals(otherIdInterval); })); } /** * Apply the current delete operation to a LogootSplit document. * @param {LogootSRopes} doc - the LogootSplit document on which the deletions wil be performed. * @return {TextDelete[]} the list of deletions to be applied on the sequence representing the document content. */ execute(doc) { return arrayConcat.apply([], this.lid.map((aId) => doc.delBlock(aId, this.author))); } } //# sourceMappingURL=logootsdel.js.map