Changeset: Migrate from opAssembler() to serializeOps()

This commit is contained in:
Richard Hansen 2021-10-12 03:01:15 -04:00
parent d5a7bf7a8f
commit b5486b6753
4 changed files with 29 additions and 26 deletions

View file

@ -36,6 +36,7 @@
* `opAttributeValue()` * `opAttributeValue()`
* `opIterator()`: Deprecated in favor of the new `deserializeOps()` generator * `opIterator()`: Deprecated in favor of the new `deserializeOps()` generator
function. function.
* `opAssembler()`: Deprecated in favor of the new `serializeOps()` function.
* `appendATextToAssembler()`: Deprecated in favor of the new `opsFromAText()` * `appendATextToAssembler()`: Deprecated in favor of the new `opsFromAText()`
generator function. generator function.
* `newOp()`: Deprecated in favor of the new `Op` class. * `newOp()`: Deprecated in favor of the new `Op` class.

View file

@ -206,28 +206,26 @@ PadDiff.prototype._extendChangesetWithAuthor = (changeset, author, apool) => {
// unpack // unpack
const unpacked = Changeset.unpack(changeset); const unpacked = Changeset.unpack(changeset);
const assem = Changeset.opAssembler();
// create deleted attribs // create deleted attribs
const authorAttrib = apool.putAttrib(['author', author || '']); const authorAttrib = apool.putAttrib(['author', author || '']);
const deletedAttrib = apool.putAttrib(['removed', true]); const deletedAttrib = apool.putAttrib(['removed', true]);
const attribs = `*${Changeset.numToString(authorAttrib)}*${Changeset.numToString(deletedAttrib)}`; const attribs = `*${Changeset.numToString(authorAttrib)}*${Changeset.numToString(deletedAttrib)}`;
for (const operator of Changeset.deserializeOps(unpacked.ops)) { const serializedOps = Changeset.serializeOps((function* () {
if (operator.opcode === '-') { for (const operator of Changeset.deserializeOps(unpacked.ops)) {
// this is a delete operator, extend it with the author if (operator.opcode === '-') {
operator.attribs = attribs; // this is a delete operator, extend it with the author
} else if (operator.opcode === '=' && operator.attribs) { operator.attribs = attribs;
// this is operator changes only attributes, let's mark which author did that } else if (operator.opcode === '=' && operator.attribs) {
operator.attribs += `*${Changeset.numToString(authorAttrib)}`; // this is operator changes only attributes, let's mark which author did that
operator.attribs += `*${Changeset.numToString(authorAttrib)}`;
}
yield operator;
} }
})());
// append the new operator to our assembler
assem.append(operator);
}
// return the modified changeset // return the modified changeset
return Changeset.pack(unpacked.oldLen, unpacked.newLen, assem.toString(), unpacked.charBank); return Changeset.pack(unpacked.oldLen, unpacked.newLen, serializedOps, unpacked.charBank);
}; };
// this method is 80% like Changeset.inverse. I just changed so instead of reverting, // this method is 80% like Changeset.inverse. I just changed so instead of reverting,

View file

@ -297,7 +297,7 @@ const copyOp = (op1, op2 = new Op()) => Object.assign(op2, op1);
* @param {Iterable<Op>} ops - Iterable of operations to serialize. * @param {Iterable<Op>} ops - Iterable of operations to serialize.
* @returns {string} A string containing the encoded op data (example: '|5=2p=v*4*5+1'). * @returns {string} A string containing the encoded op data (example: '|5=2p=v*4*5+1').
*/ */
const serializeOps = (ops) => { exports.serializeOps = (ops) => {
let res = ''; let res = '';
for (const op of ops) res += op.toString(); for (const op of ops) res += op.toString();
return res; return res;
@ -305,6 +305,8 @@ const serializeOps = (ops) => {
/** /**
* Serializes a sequence of Ops. * Serializes a sequence of Ops.
*
* @deprecated Use `serializeOps` instead.
*/ */
class OpAssembler { class OpAssembler {
constructor() { constructor() {
@ -324,7 +326,7 @@ class OpAssembler {
} }
toString() { toString() {
return serializeOps(this._ops); return exports.serializeOps(this._ops);
} }
} }
@ -334,12 +336,11 @@ class OpAssembler {
*/ */
class MergingOpAssembler { class MergingOpAssembler {
constructor() { constructor() {
this._assem = new OpAssembler();
this.clear(); this.clear();
} }
clear() { clear() {
this._assem.clear(); this._assem = [];
this._bufOp = new Op(); this._bufOp = new Op();
// If we get, for example, insertions [xxx\n,yyy], those don't merge, but if we get // If we get, for example, insertions [xxx\n,yyy], those don't merge, but if we get
// [xxx\n,yyy,zzz\n], that merges to [xxx\nyyyzzz\n]. This variable stores the length of yyy and // [xxx\n,yyy,zzz\n], that merges to [xxx\nyyyzzz\n]. This variable stores the length of yyy and
@ -352,11 +353,11 @@ class MergingOpAssembler {
if (isEndDocument && this._bufOp.opcode === '=' && !this._bufOp.attribs) { if (isEndDocument && this._bufOp.opcode === '=' && !this._bufOp.attribs) {
// final merged keep, leave it implicit // final merged keep, leave it implicit
} else { } else {
this._assem.append(this._bufOp); this._assem.push(copyOp(this._bufOp));
if (this._bufOpAdditionalCharsAfterNewline) { if (this._bufOpAdditionalCharsAfterNewline) {
this._bufOp.chars = this._bufOpAdditionalCharsAfterNewline; this._bufOp.chars = this._bufOpAdditionalCharsAfterNewline;
this._bufOp.lines = 0; this._bufOp.lines = 0;
this._assem.append(this._bufOp); this._assem.push(copyOp(this._bufOp));
this._bufOpAdditionalCharsAfterNewline = 0; this._bufOpAdditionalCharsAfterNewline = 0;
} }
} }
@ -390,7 +391,7 @@ class MergingOpAssembler {
toString() { toString() {
this._flush(); this._flush();
return this._assem.toString(); return exports.serializeOps(this._assem);
} }
} }
@ -590,9 +591,14 @@ exports.smartOpAssembler = () => new SmartOpAssembler();
exports.mergingOpAssembler = () => new MergingOpAssembler(); exports.mergingOpAssembler = () => new MergingOpAssembler();
/** /**
* @deprecated Use `serializeOps` instead.
* @returns {OpAssembler} * @returns {OpAssembler}
*/ */
exports.opAssembler = () => new OpAssembler(); exports.opAssembler = () => {
padutils.warnDeprecated(
'Changeset.opAssembler() is deprecated; use Changeset.serializeOps() instead');
return new OpAssembler();
};
/** /**
* A custom made String Iterator * A custom made String Iterator

View file

@ -3,11 +3,9 @@
const Changeset = require('../../../static/js/Changeset'); const Changeset = require('../../../static/js/Changeset');
describe('easysync-assembler', function () { describe('easysync-assembler', function () {
it('opAssembler', async function () { it('deserialize and serialize', async function () {
const x = '-c*3*4+6|3=az*asdf0*1*2*3+1=1-1+1*0+1=1-1+1|c=c-1'; const x = '-c*3*4+6|3=az*asdf0*1*2*3+1=1-1+1*0+1=1-1+1|c=c-1';
const assem = Changeset.opAssembler(); expect(Changeset.serializeOps(Changeset.deserializeOps(x))).to.equal(x);
for (const op of Changeset.deserializeOps(x)) assem.append(op);
expect(assem.toString()).to.equal(x);
}); });
it('smartOpAssembler', async function () { it('smartOpAssembler', async function () {