changesets
Advanced tools
Comparing version 0.4.0 to 1.0.0
@@ -41,2 +41,3 @@ (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | ||
} | ||
},{"./Changeset":2,"./operations/Insert":7,"./operations/Retain":8,"./operations/Skip":9}],2:[function(require,module,exports){ | ||
@@ -55,6 +56,6 @@ /*! | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
@@ -79,3 +80,3 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
this.outputLength = 0 | ||
if(!Array.isArray(ops)) ops = arguments | ||
@@ -108,3 +109,3 @@ for(var i=0; i<ops.length; i++) { | ||
var Builder = require('./Builder') | ||
/** | ||
@@ -149,3 +150,7 @@ * Returns an array containing the ops that are within the passed range | ||
} | ||
if(otherCs.inputLength !== this.outputLength) { | ||
throw new Error("Changeset lengths for merging don't match! Input length of younger cs: "+otherCs.inputLength+', output length of older cs:'+this.outputLength) | ||
} | ||
var newops = [] | ||
@@ -158,3 +163,3 @@ , addPtr1 = 0 | ||
, newremovendum = '' | ||
zip(this, otherCs, function(op1, op2) { | ||
@@ -164,11 +169,13 @@ // console.log(newops) | ||
if(op1 && !op1.input && (!op2 || op2.input || left)) { // if it's a tie -- "left" breaks it. | ||
// I'm deleting something -- the other cs can't know that, so just overtake my op | ||
if(op1 && !op1.output) { | ||
newops.push(op1.merge().clone()) | ||
newaddendum += this.addendum.substr(addPtr1, op1.length) // overtake added chars | ||
addPtr1 += op1.length | ||
newremovendum += this.removendum.substr(remPtr1, op1.length) // overtake added chars | ||
remPtr1 += op1.length | ||
op1.length = 0 // don't gimme that one again. | ||
return | ||
} | ||
if(op2 && !op2.input && (!op1 || op1.input || !left)) {// if it's a tie -- "left" breaks it. | ||
// op2 is an insert | ||
if(op2 && !op2.input) { | ||
newops.push(op2.merge().clone()) | ||
@@ -180,39 +187,43 @@ newaddendum += otherCs.addendum.substr(addPtr2, op2.length) // overtake added chars | ||
} | ||
// XXX Move addendum and removendum stuff to indiv. ops | ||
// XXX Move everything below this to op1.merge(op2) | ||
if(op2 && !op2.output) { | ||
newops.push(op2.merge(op1).clone()) | ||
newremovendum += otherCs.removendum.substr(remPtr2, op2.length) // overtake removed chars | ||
remPtr2 += op2.length | ||
if(op1) op1.length = 0 // don't gimme these again. | ||
op2.length = 0 | ||
// op2 is either a retain or a skip | ||
if(op2 && op2.input && op1) { | ||
// op2 retains whatever we do here (retain or insert), so just clone my op | ||
if(op2.output) { | ||
newops.push(op1.merge(op2).clone()) | ||
if(!op1.input) { // overtake addendum | ||
newaddendum += this.addendum.substr(addPtr1, op1.length) | ||
addPtr1 += op1.length | ||
} | ||
op1.length = 0 // don't gimme these again | ||
op2.length = 0 | ||
}else | ||
// op2 deletes my retain here, so just clone the delete | ||
// (op1 can only be a retain and no skip here, cause we've handled skips above already) | ||
if(!op2.output && op1.input) { | ||
newops.push(op2.merge(op1).clone()) | ||
newremovendum += otherCs.removendum.substr(remPtr2, op2.length) // overtake added chars | ||
remPtr2 += op2.length | ||
op1.length = 0 // don't gimme these again | ||
op2.length = 0 | ||
}else | ||
//otherCs deletes something I added (-1) +1 = 0 | ||
{ | ||
addPtr1 += op1.length | ||
op1.length = 0 // don't gimme these again | ||
op2.length = 0 | ||
} | ||
return | ||
} | ||
if(op1 && !op1.output) { | ||
newops.push(op1.merge(op2).clone()) | ||
newremovendum += this.removendum.substr(remPtr1, op1.length) // overtake removed chars | ||
remPtr1 += op1.length | ||
op1.length = 0 // don't gimme that one again. | ||
if(op2) op2.length = 0 | ||
return | ||
} | ||
if((op1 && op1.input == op1.output)) { | ||
newops.push(op1.merge(op2).clone()) | ||
op1.length = 0 // don't gimme these again. | ||
if(op2) op2.length = 0 | ||
return | ||
} | ||
console.log('oops', arguments) | ||
throw new Error('oops. This case hasn\'t been considered by the developer (error code: PBCAC)') | ||
}.bind(this)) | ||
var newCs = new Changeset(newops) | ||
newCs.addendum = newaddendum | ||
newCs.removendum = newremovendum | ||
return newCs | ||
@@ -228,3 +239,3 @@ } | ||
, opstack2 = cs2.map(function(op) {return op.clone()}) | ||
var op2, op1 | ||
@@ -234,3 +245,3 @@ while(opstack1.length || opstack2.length) {// iterate through all outstanding ops of this cs | ||
op2 = opstack2[0]? opstack2[0].clone() : null | ||
if(op1) { | ||
@@ -241,3 +252,3 @@ if(op2) op1 = op1.derive(Math.min(op1.length, op2.length)) // slice 'em into equally long pieces | ||
} | ||
if(op2) { | ||
@@ -250,3 +261,3 @@ if(op1) op2 = op2.derive(Math.min(op1.length, op2.length)) // slice 'em into equally long pieces | ||
func(op1, op2) | ||
if(op1 && op1.length) opstack1.unshift(op1) | ||
@@ -264,6 +275,6 @@ if(op2 && op2.length) opstack2.unshift(op2) | ||
* This is basically like a applying the other cs on this one. | ||
* | ||
* | ||
* @param otherCs <Changeset> | ||
* @param left <boolean> Which op to choose if there's an insert tie (If you use this function in a distributed, synchronous environment, be sure to invert this param on the other site, otherwise it can be omitted safely) | ||
* | ||
* | ||
* @returns <Changeset> | ||
@@ -275,7 +286,7 @@ */ | ||
} | ||
if(this.inputLength != otherCs.inputLength) { | ||
throw new Error('Can\'t transform changesets with differing inputLength: '+this.inputLength+' and '+otherCs.inputLength) | ||
} | ||
var transformation = new ChangesetTransform(this, [new Retain(Infinity)]) | ||
@@ -289,3 +300,3 @@ otherCs.forEach(function(op) { | ||
}.bind(this)) | ||
return transformation.result() | ||
@@ -296,3 +307,3 @@ } | ||
* Exclusion Transformation (ET) or Backwards Transformation | ||
* | ||
* | ||
* transforms all operations in the current changeset against the operations | ||
@@ -315,3 +326,3 @@ * in another changeset in such a way that the impact of the latter are effectively excluded | ||
* Returns the inverse Changeset of the current one | ||
* | ||
* | ||
* Changeset.invert().apply(Changeset.apply(document)) == document | ||
@@ -324,3 +335,3 @@ */ | ||
})) | ||
// removendum becomes addendum and vice versa | ||
@@ -339,3 +350,3 @@ newCs.addendum = this.removendum | ||
if(input.length != this.inputLength) throw new Error('Input length doesn\'t match expected length. expected: '+this.inputLength+'; actual: '+input.length) | ||
var operation = new TextTransform(input, this.addendum, this.removendum) | ||
@@ -364,3 +375,3 @@ | ||
} | ||
for(var i=0; i<op.length; i++) string += op.symbol | ||
@@ -384,3 +395,3 @@ return string | ||
}).join('') | ||
var addendum = this.addendum.replace(/%/g, '%25').replace(/\|/g, '%7C') | ||
@@ -396,3 +407,3 @@ , removendum = this.removendum.replace(/%/g, '%25').replace(/\|/g, '%7C') | ||
* Unserializes the output of cs.text.Changeset#toString() | ||
* | ||
* | ||
* @param packed <String> The serialized changeset | ||
@@ -410,3 +421,3 @@ * @param <cs.Changeset> | ||
if(!matches) throw new Error('Cannot unpack invalidly serialized op string') | ||
var ops = [] | ||
@@ -421,7 +432,7 @@ matches.forEach(function(s) { | ||
}) | ||
var cs = new Changeset(ops) | ||
cs.addendum = addendum | ||
cs.removendum = removendum | ||
return cs | ||
@@ -436,3 +447,3 @@ } | ||
* Returns a Changeset containing the operations needed to transform text1 into text2 | ||
* | ||
* | ||
* @param text1 <String> | ||
@@ -450,3 +461,3 @@ * @param text2 <String> | ||
var DIFF_EQUAL = 0; | ||
var ops = [] | ||
@@ -461,3 +472,3 @@ , removendum = '' | ||
} | ||
if (DIFF_INSERT == d[0]) { | ||
@@ -467,3 +478,3 @@ ops.push(new Insert(d[1].length)) | ||
} | ||
if(DIFF_EQUAL == d[0]) { | ||
@@ -473,3 +484,3 @@ ops.push(new Retain(d[1].length)) | ||
}) | ||
var cs = new Changeset(ops) | ||
@@ -480,2 +491,3 @@ cs.addendum = addendum | ||
} | ||
},{"./Builder":1,"./ChangesetTransform":3,"./TextTransform":5,"./operations/Insert":7,"./operations/Retain":8,"./operations/Skip":9}],3:[function(require,module,exports){ | ||
@@ -494,6 +506,6 @@ /*! | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
@@ -570,2 +582,3 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
} | ||
},{"./Changeset":2,"./operations/Insert":7,"./operations/Retain":8,"./operations/Skip":9}],4:[function(require,module,exports){ | ||
@@ -588,2 +601,3 @@ function Operator() { | ||
} | ||
},{}],5:[function(require,module,exports){ | ||
@@ -602,6 +616,6 @@ /*! | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
@@ -664,2 +678,3 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
} | ||
},{"./Changeset":2,"./operations/Insert":7,"./operations/Retain":8,"./operations/Skip":9}],6:[function(require,module,exports){ | ||
@@ -678,6 +693,6 @@ /*! | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
@@ -696,3 +711,3 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
, Insert = require('./operations/Insert') | ||
exports.Operator = require('./Operator') | ||
@@ -735,3 +750,3 @@ exports.Changeset = Changeset | ||
* create([initialText]) | ||
* | ||
* | ||
* creates a snapshot (optionally with supplied intial text) | ||
@@ -743,3 +758,3 @@ */ | ||
/** | ||
/** | ||
* Apply a changeset on a snapshot creating a new one | ||
@@ -779,2 +794,3 @@ * | ||
} | ||
},{"./Changeset":2,"./Operator":4,"./operations/Insert":7,"./operations/Retain":8,"./operations/Skip":9}],7:[function(require,module,exports){ | ||
@@ -793,6 +809,6 @@ /*! | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
@@ -854,2 +870,3 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
} | ||
},{"../Operator":4,"./Retain":8,"./Skip":9}],8:[function(require,module,exports){ | ||
@@ -868,6 +885,6 @@ /*! | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
@@ -925,2 +942,3 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
} | ||
},{"../Operator":4}],9:[function(require,module,exports){ | ||
@@ -939,6 +957,6 @@ /*! | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
@@ -971,3 +989,3 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// True inheritance | ||
Skip.prototype = Object.create(Operator.prototype, { | ||
Skip.prototype = Object.create(Operator.prototype, { | ||
constructor: { | ||
@@ -1004,2 +1022,3 @@ value: Skip, | ||
} | ||
},{"../Changeset":2,"../Operator":4,"./Insert":7,"./Retain":8}]},{},[6]) |
@@ -5,3 +5,3 @@ { | ||
"description": "A Changeset library incorporating an operational transformation (OT) algorithm -- for node and the browser!", | ||
"version": "0.4.0", | ||
"version": "1.0.0", | ||
"keywords": [ | ||
@@ -27,8 +27,11 @@ "operational transformation", | ||
"lib/index.js", | ||
"lib/Operation.js", | ||
"lib/Operator.js", | ||
"lib/Changeset.js", | ||
"lib/operations/Skip.js", | ||
"lib/operations/Insert.js", | ||
"lib/operations/Retain.js" | ||
"lib/operations/Retain.js", | ||
"lib/Builder.js", | ||
"lib/TextTransform.js", | ||
"lib/ChangesetTransform.js" | ||
] | ||
} |
@@ -39,2 +39,2 @@ var Changeset = require('./Changeset') | ||
return cs | ||
} | ||
} |
@@ -13,6 +13,6 @@ /*! | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
@@ -37,3 +37,3 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
this.outputLength = 0 | ||
if(!Array.isArray(ops)) ops = arguments | ||
@@ -66,3 +66,3 @@ for(var i=0; i<ops.length; i++) { | ||
var Builder = require('./Builder') | ||
/** | ||
@@ -107,3 +107,7 @@ * Returns an array containing the ops that are within the passed range | ||
} | ||
if(otherCs.inputLength !== this.outputLength) { | ||
throw new Error("Changeset lengths for merging don't match! Input length of younger cs: "+otherCs.inputLength+', output length of older cs:'+this.outputLength) | ||
} | ||
var newops = [] | ||
@@ -116,3 +120,3 @@ , addPtr1 = 0 | ||
, newremovendum = '' | ||
zip(this, otherCs, function(op1, op2) { | ||
@@ -122,11 +126,13 @@ // console.log(newops) | ||
if(op1 && !op1.input && (!op2 || op2.input || left)) { // if it's a tie -- "left" breaks it. | ||
// I'm deleting something -- the other cs can't know that, so just overtake my op | ||
if(op1 && !op1.output) { | ||
newops.push(op1.merge().clone()) | ||
newaddendum += this.addendum.substr(addPtr1, op1.length) // overtake added chars | ||
addPtr1 += op1.length | ||
newremovendum += this.removendum.substr(remPtr1, op1.length) // overtake added chars | ||
remPtr1 += op1.length | ||
op1.length = 0 // don't gimme that one again. | ||
return | ||
} | ||
if(op2 && !op2.input && (!op1 || op1.input || !left)) {// if it's a tie -- "left" breaks it. | ||
// op2 is an insert | ||
if(op2 && !op2.input) { | ||
newops.push(op2.merge().clone()) | ||
@@ -138,39 +144,43 @@ newaddendum += otherCs.addendum.substr(addPtr2, op2.length) // overtake added chars | ||
} | ||
// XXX Move addendum and removendum stuff to indiv. ops | ||
// XXX Move everything below this to op1.merge(op2) | ||
if(op2 && !op2.output) { | ||
newops.push(op2.merge(op1).clone()) | ||
newremovendum += otherCs.removendum.substr(remPtr2, op2.length) // overtake removed chars | ||
remPtr2 += op2.length | ||
if(op1) op1.length = 0 // don't gimme these again. | ||
op2.length = 0 | ||
// op2 is either a retain or a skip | ||
if(op2 && op2.input && op1) { | ||
// op2 retains whatever we do here (retain or insert), so just clone my op | ||
if(op2.output) { | ||
newops.push(op1.merge(op2).clone()) | ||
if(!op1.input) { // overtake addendum | ||
newaddendum += this.addendum.substr(addPtr1, op1.length) | ||
addPtr1 += op1.length | ||
} | ||
op1.length = 0 // don't gimme these again | ||
op2.length = 0 | ||
}else | ||
// op2 deletes my retain here, so just clone the delete | ||
// (op1 can only be a retain and no skip here, cause we've handled skips above already) | ||
if(!op2.output && op1.input) { | ||
newops.push(op2.merge(op1).clone()) | ||
newremovendum += otherCs.removendum.substr(remPtr2, op2.length) // overtake added chars | ||
remPtr2 += op2.length | ||
op1.length = 0 // don't gimme these again | ||
op2.length = 0 | ||
}else | ||
//otherCs deletes something I added (-1) +1 = 0 | ||
{ | ||
addPtr1 += op1.length | ||
op1.length = 0 // don't gimme these again | ||
op2.length = 0 | ||
} | ||
return | ||
} | ||
if(op1 && !op1.output) { | ||
newops.push(op1.merge(op2).clone()) | ||
newremovendum += this.removendum.substr(remPtr1, op1.length) // overtake removed chars | ||
remPtr1 += op1.length | ||
op1.length = 0 // don't gimme that one again. | ||
if(op2) op2.length = 0 | ||
return | ||
} | ||
if((op1 && op1.input == op1.output)) { | ||
newops.push(op1.merge(op2).clone()) | ||
op1.length = 0 // don't gimme these again. | ||
if(op2) op2.length = 0 | ||
return | ||
} | ||
console.log('oops', arguments) | ||
throw new Error('oops. This case hasn\'t been considered by the developer (error code: PBCAC)') | ||
}.bind(this)) | ||
var newCs = new Changeset(newops) | ||
newCs.addendum = newaddendum | ||
newCs.removendum = newremovendum | ||
return newCs | ||
@@ -186,3 +196,3 @@ } | ||
, opstack2 = cs2.map(function(op) {return op.clone()}) | ||
var op2, op1 | ||
@@ -192,3 +202,3 @@ while(opstack1.length || opstack2.length) {// iterate through all outstanding ops of this cs | ||
op2 = opstack2[0]? opstack2[0].clone() : null | ||
if(op1) { | ||
@@ -199,3 +209,3 @@ if(op2) op1 = op1.derive(Math.min(op1.length, op2.length)) // slice 'em into equally long pieces | ||
} | ||
if(op2) { | ||
@@ -208,3 +218,3 @@ if(op1) op2 = op2.derive(Math.min(op1.length, op2.length)) // slice 'em into equally long pieces | ||
func(op1, op2) | ||
if(op1 && op1.length) opstack1.unshift(op1) | ||
@@ -222,6 +232,6 @@ if(op2 && op2.length) opstack2.unshift(op2) | ||
* This is basically like a applying the other cs on this one. | ||
* | ||
* | ||
* @param otherCs <Changeset> | ||
* @param left <boolean> Which op to choose if there's an insert tie (If you use this function in a distributed, synchronous environment, be sure to invert this param on the other site, otherwise it can be omitted safely) | ||
* | ||
* | ||
* @returns <Changeset> | ||
@@ -233,7 +243,7 @@ */ | ||
} | ||
if(this.inputLength != otherCs.inputLength) { | ||
throw new Error('Can\'t transform changesets with differing inputLength: '+this.inputLength+' and '+otherCs.inputLength) | ||
} | ||
var transformation = new ChangesetTransform(this, [new Retain(Infinity)]) | ||
@@ -247,3 +257,3 @@ otherCs.forEach(function(op) { | ||
}.bind(this)) | ||
return transformation.result() | ||
@@ -254,3 +264,3 @@ } | ||
* Exclusion Transformation (ET) or Backwards Transformation | ||
* | ||
* | ||
* transforms all operations in the current changeset against the operations | ||
@@ -273,3 +283,3 @@ * in another changeset in such a way that the impact of the latter are effectively excluded | ||
* Returns the inverse Changeset of the current one | ||
* | ||
* | ||
* Changeset.invert().apply(Changeset.apply(document)) == document | ||
@@ -282,3 +292,3 @@ */ | ||
})) | ||
// removendum becomes addendum and vice versa | ||
@@ -297,3 +307,3 @@ newCs.addendum = this.removendum | ||
if(input.length != this.inputLength) throw new Error('Input length doesn\'t match expected length. expected: '+this.inputLength+'; actual: '+input.length) | ||
var operation = new TextTransform(input, this.addendum, this.removendum) | ||
@@ -322,3 +332,3 @@ | ||
} | ||
for(var i=0; i<op.length; i++) string += op.symbol | ||
@@ -342,3 +352,3 @@ return string | ||
}).join('') | ||
var addendum = this.addendum.replace(/%/g, '%25').replace(/\|/g, '%7C') | ||
@@ -354,3 +364,3 @@ , removendum = this.removendum.replace(/%/g, '%25').replace(/\|/g, '%7C') | ||
* Unserializes the output of cs.text.Changeset#toString() | ||
* | ||
* | ||
* @param packed <String> The serialized changeset | ||
@@ -368,3 +378,3 @@ * @param <cs.Changeset> | ||
if(!matches) throw new Error('Cannot unpack invalidly serialized op string') | ||
var ops = [] | ||
@@ -379,7 +389,7 @@ matches.forEach(function(s) { | ||
}) | ||
var cs = new Changeset(ops) | ||
cs.addendum = addendum | ||
cs.removendum = removendum | ||
return cs | ||
@@ -394,3 +404,3 @@ } | ||
* Returns a Changeset containing the operations needed to transform text1 into text2 | ||
* | ||
* | ||
* @param text1 <String> | ||
@@ -408,3 +418,3 @@ * @param text2 <String> | ||
var DIFF_EQUAL = 0; | ||
var ops = [] | ||
@@ -419,3 +429,3 @@ , removendum = '' | ||
} | ||
if (DIFF_INSERT == d[0]) { | ||
@@ -425,3 +435,3 @@ ops.push(new Insert(d[1].length)) | ||
} | ||
if(DIFF_EQUAL == d[0]) { | ||
@@ -431,3 +441,3 @@ ops.push(new Retain(d[1].length)) | ||
}) | ||
var cs = new Changeset(ops) | ||
@@ -437,2 +447,2 @@ cs.addendum = addendum | ||
return cs | ||
} | ||
} |
@@ -13,6 +13,6 @@ /*! | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
@@ -88,2 +88,2 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
return newCs | ||
} | ||
} |
@@ -13,6 +13,6 @@ /*! | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
@@ -31,3 +31,3 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
, Insert = require('./operations/Insert') | ||
exports.Operator = require('./Operator') | ||
@@ -70,3 +70,3 @@ exports.Changeset = Changeset | ||
* create([initialText]) | ||
* | ||
* | ||
* creates a snapshot (optionally with supplied intial text) | ||
@@ -78,3 +78,3 @@ */ | ||
/** | ||
/** | ||
* Apply a changeset on a snapshot creating a new one | ||
@@ -113,2 +113,2 @@ * | ||
return op.invert() | ||
} | ||
} |
@@ -13,6 +13,6 @@ /*! | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
@@ -73,2 +73,2 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
return new Insert(parseInt(data, 36)) | ||
} | ||
} |
@@ -13,6 +13,6 @@ /*! | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
@@ -67,3 +67,3 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
newop[a] = 1 | ||
// add and remove annihilate each other | ||
@@ -83,8 +83,8 @@ if(newop[-a]) { | ||
, attribs = {} | ||
data.forEach(function(a) { | ||
attribs[a] = 1 | ||
}) | ||
return new Mark(length, attribs) | ||
} | ||
} |
@@ -13,6 +13,6 @@ /*! | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
@@ -69,2 +69,2 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
return new Retain(parseInt(data, 36)) | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
/*! | ||
/*! | ||
* changesets | ||
@@ -13,6 +13,6 @@ * A Changeset library incorporating operational transformation (OT) | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
@@ -45,3 +45,3 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// True inheritance | ||
Skip.prototype = Object.create(Operator.prototype, { | ||
Skip.prototype = Object.create(Operator.prototype, { | ||
constructor: { | ||
@@ -77,2 +77,2 @@ value: Skip, | ||
return new Skip(parseInt(data, 36)) | ||
} | ||
} |
@@ -16,2 +16,2 @@ function Operator() { | ||
return this.symbol + (this.length).toString(36) | ||
} | ||
} |
@@ -13,6 +13,6 @@ /*! | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
@@ -74,2 +74,2 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
return this.output | ||
} | ||
} |
{ | ||
"name": "changesets", | ||
"version": "0.4.0", | ||
"version": "1.0.0", | ||
"description": "Changeset library incorporating an operational transformation (OT) algorithm - for node and the browser, with shareJS support", | ||
@@ -5,0 +5,0 @@ "repository": { |
@@ -10,4 +10,6 @@ # changesets [![Build Status](https://travis-ci.org/marcelklehr/changesets.png?branch=master)](https://travis-ci.org/marcelklehr/changesets) | ||
News: *changesets* now supports the ottypes API spec of shareJS. | ||
News: *changesets* now supports the ottypes API spec of shareJS. If you'd like a more unixy, transport agnostic tool, though, check out [gulf](https://github.com/marcelklehr/gulf). | ||
News: Changesets v1.0.0 corrects the semantics of Changeset#merge, which now requires you to pass a consecutive changeset, instead of one that was created concurrently to the first one. This is inline with shareJS's API spec. | ||
## Install | ||
@@ -220,2 +222,5 @@ `npm install changesets` or `component install marcelklehr/changesets` | ||
1.0.0 | ||
* Change semantics of Changeset#merge to adhere to logic as well as shareJS spec | ||
0.4.0 | ||
@@ -222,0 +227,0 @@ * Modularize operations |
@@ -13,6 +13,6 @@ /*! | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
@@ -48,3 +48,2 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
;// Insert onto Insert | ||
var ITset = | ||
[ ["123", ["a123", "123b"], "a123b", "Insert onto Insert; o1.pos < o2.pos"] | ||
@@ -79,3 +78,3 @@ , ["123", ["1a23", "1b23"], "1ab23", "Insert onto Insert; o1.pos = o2.pos"] | ||
] | ||
ITset.forEach(function(test, i) { | ||
.forEach(function(test, i) { | ||
var batch = {} | ||
@@ -88,3 +87,3 @@ batch[test[3]] = { | ||
console.log("\n\n", test[0]) | ||
console.log("\n\n", test[0]) | ||
console.dir(cs1.inspect()) | ||
@@ -111,37 +110,7 @@ console.dir(cs2.inspect()) | ||
// MERGING | ||
ITset.forEach(function(test, i) { | ||
var batch = {}; | ||
batch[test[3]] = { | ||
topic: function() { | ||
try{ | ||
var cs1 = constructChangeset(test[0],test[1][0]) | ||
, cs2 = constructChangeset(test[0],test[1][1]) | ||
, merged | ||
console.log("\n\n", test[0]+': merging') | ||
console.dir(cs1.inspect()) | ||
console.dir(cs2.inspect()) | ||
merged = cs1.merge(cs2, /*left:*/true) | ||
console.log('=>', merged.inspect()) | ||
return merged.apply(test[0]) | ||
}catch(e){ | ||
console.log(e.stack||e) | ||
process.exit(1) | ||
} | ||
}, | ||
'should be correctly merged': function(err, text) { | ||
assert.ifError(err) | ||
assert.equal(test[2], text) | ||
} | ||
} | ||
suite.addBatch(batch) | ||
}) | ||
// ET | ||
;// Insert minus Insert | ||
; | ||
ETset = | ||
// Insert minus Insert | ||
[ [["123", "123b", "a123b"], "a123", "Insert minus Insert; o2.pos < o1.pos"] | ||
@@ -167,3 +136,3 @@ , [["123", "b123", "b12a3"], "12a3", "Insert minus Insert; o1.pos < o2.pos"] | ||
] | ||
.forEach(function(test, i) { | ||
ETset.forEach(function(test, i) { | ||
var batch = {} | ||
@@ -193,2 +162,35 @@ batch[test[2]] = { | ||
// MERGING | ||
ETset.forEach(function(test, i) { | ||
var batch = {}; | ||
batch[test[2]] = { | ||
topic: function() { | ||
try{ | ||
var cs1 = constructChangeset(test[0][0],test[0][1]) | ||
, cs2 = constructChangeset(test[0][1],test[0][2]) | ||
, merged | ||
console.log("\n\n", test[0]+': merging') | ||
console.dir(cs1.inspect()) | ||
console.dir(cs2.inspect()) | ||
merged = cs1.merge(cs2, /*left:*/true) | ||
console.log('=>', merged.inspect()) | ||
return merged.apply(test[0][0]) | ||
}catch(e){ | ||
console.log(e.stack||e) | ||
process.exit(1) | ||
} | ||
}, | ||
'should be correctly merged': function(err, text) { | ||
assert.ifError(err) | ||
assert.equal(test[0][2], text) | ||
} | ||
} | ||
suite.addBatch(batch) | ||
}) | ||
var packUnpack1 = "012345678901234567890123456789" | ||
@@ -230,3 +232,3 @@ , packUnpack2 = "012345678aaaaaaaaaaaaaaaaaaaaaa8aaaaaaaaaaaaaaaaaaaa9" | ||
console.log("\n\n "+test[0]+": inverting ", test[1]) | ||
var cs1 = constructChangeset(test[0], test[1]) | ||
@@ -268,3 +270,3 @@ , cs2 = cs1.invert() | ||
cs.apply(cs.apply("1234")) | ||
returnthis.callback() | ||
@@ -271,0 +273,0 @@ } |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
86833
2036
1
235