Comparing version 11.2.1 to 11.2.2
{ | ||
"name": "yjs", | ||
"version": "11.2.1", | ||
"version": "11.2.2", | ||
"homepage": "y-js.org", | ||
@@ -5,0 +5,0 @@ "authors": [ |
@@ -10,4 +10,4 @@ /* global Y, Quill */ | ||
connector: { | ||
name: 'websockets-client', | ||
room: 'richtext-example' | ||
name: 'webrtc', | ||
room: 'richtext-example-quill-beta' | ||
}, | ||
@@ -22,9 +22,18 @@ sourceDir: '/bower_components', | ||
// create quill element | ||
window.quill = new Quill('#editor', { | ||
window.quill = new Quill('#quill', { | ||
modules: { | ||
'toolbar': { container: '#toolbar' }, | ||
'link-tooltip': true | ||
formula: true, | ||
syntax: true, | ||
toolbar: [ | ||
[{ size: ['small', false, 'large', 'huge'] }], | ||
['bold', 'italic', 'underline'], | ||
[{ color: [] }, { background: [] }], // Snow theme fills in values | ||
[{ script: 'sub' }, { script: 'super' }], | ||
['link', 'image'], | ||
['link', 'code-block'], | ||
[{list: 'ordered' }] | ||
] | ||
}, | ||
theme: 'snow' | ||
}) | ||
}); | ||
// bind quill to richtext type | ||
@@ -31,0 +40,0 @@ y.share.richtext.bind(window.quill) |
@@ -51,3 +51,5 @@ | ||
.pipe($.sourcemaps.init({loadMaps: true})) | ||
.pipe($.if(!options.debug, $.uglify())) | ||
.pipe($.if(!options.debug, $.uglify().on('error', function (e) { | ||
console.log('\x07', e.message, JSON.stringify(e)); return this.end() | ||
}))) | ||
.pipe($.sourcemaps.write('.')) | ||
@@ -54,0 +56,0 @@ .pipe(gulp.dest('./dist/'))) |
{ | ||
"name": "yjs", | ||
"version": "11.2.1", | ||
"version": "11.2.2", | ||
"description": "A framework for real-time p2p shared editing on arbitrary complex data types", | ||
@@ -45,2 +45,3 @@ "main": "./src/y.js", | ||
"devDependencies": { | ||
"babel-eslint": "^5.0.0-beta6", | ||
"babel-plugin-transform-runtime": "^6.1.18", | ||
@@ -73,8 +74,8 @@ "babel-preset-es2015": "^6.1.18", | ||
"run-sequence": "^1.1.4", | ||
"seedrandom": "^2.4.2", | ||
"standard": "^5.2.2", | ||
"vinyl-buffer": "^1.0.0", | ||
"vinyl-source-stream": "^1.1.0", | ||
"babel-eslint": "^5.0.0-beta6" | ||
"vinyl-source-stream": "^1.1.0" | ||
}, | ||
"dependencies": {} | ||
} |
@@ -7,3 +7,3 @@ /* global getRandom, async */ | ||
users: {}, | ||
buffers: {}, // TODO: reimplement this idea. This does not cover all cases!! Here, you have a queue which is unrealistic (i.e. think about multiple incoming connections) | ||
buffers: {}, | ||
removeUser: function (user) { | ||
@@ -10,0 +10,0 @@ for (var i in this.users) { |
@@ -370,3 +370,4 @@ /* @flow */ | ||
if (defined == null) { | ||
var isGarbageCollected = yield* this.isGarbageCollected(op.id) | ||
var opid = op.id | ||
var isGarbageCollected = yield* this.isGarbageCollected(opid) | ||
if (!isGarbageCollected) { | ||
@@ -376,3 +377,6 @@ yield* Y.Struct[op.struct].execute.call(this, op) | ||
yield* this.store.operationAdded(this, op) | ||
if (!Y.utils.compareIds(opid, op.id)) { | ||
// operationAdded changed op | ||
op = yield* this.getOperation(opid) | ||
} | ||
// if insertion, try to combine with left | ||
@@ -379,0 +383,0 @@ yield* this.tryCombineWithLeft(op) |
@@ -14,2 +14,3 @@ /* eslint-env browser, jasmine */ | ||
require('../../y-indexeddb/src/IndexedDB.js')(Y) | ||
require('../../y-leveldb/src/LevelDB.js')(Y) | ||
module.exports = Y | ||
@@ -27,2 +28,24 @@ | ||
// Helper methods for the random number generator | ||
Math.seedrandom = require('seedrandom') | ||
g.generateRandomSeed = function generateRandomSeed () { | ||
var seed | ||
if (typeof window !== 'undefined' && window.location.hash.length > 1) { | ||
seed = window.location.hash.slice(1) // first character is the hash! | ||
console.warn('Using random seed that was specified in the url!') | ||
} else { | ||
seed = JSON.stringify(Math.random()) | ||
} | ||
console.info('Using random seed: ' + seed) | ||
g.setRandomSeed(seed) | ||
} | ||
g.setRandomSeed = function setRandomSeed (seed) { | ||
Math.seedrandom.currentSeed = seed | ||
Math.seedrandom(Math.seedrandom.currentSeed, { global: true }) | ||
} | ||
g.generateRandomSeed() | ||
g.YConcurrency_TestingMode = true | ||
@@ -56,2 +79,4 @@ | ||
g.databases.push('indexeddb') | ||
} else { | ||
g.databases.push('leveldb') | ||
} | ||
@@ -80,3 +105,3 @@ /* | ||
function getRandomString () { | ||
var chars = 'abcdefäö' | ||
var chars = 'abcdefghijklmnopqrstuvwxyzäüöABCDEFGHIJKLMNOPQRSTUVWXYZÄÜÖ' | ||
var char = chars[getRandomNumber(chars.length)] // ü\n\n\n\n\n\n\n' | ||
@@ -93,5 +118,6 @@ var length = getRandomNumber(7) | ||
function * applyTransactions (relAmount, numberOfTransactions, objects, users, transactions, noReconnect) { | ||
g.generateRandomSeed() // create a new seed, so we can re-create the behavior | ||
for (var i = 0; i < numberOfTransactions * relAmount + 1; i++) { | ||
var r = Math.random() | ||
if (r > 0.9) { | ||
if (r > 0.95) { | ||
// 10% chance of toggling concurrent user interactions. | ||
@@ -105,3 +131,3 @@ // There will be an artificial delay until ops can be executed by the type, | ||
} else { | ||
// fixAwaitingInType will handle _debuggingAwaiting | ||
// fixAwaitingInType will handle _debuggingAwaiting | ||
return fixAwaitingInType(type) | ||
@@ -108,0 +134,0 @@ } |
@@ -505,2 +505,3 @@ /* @flow */ | ||
right.left = o.left | ||
yield* this.setOperation(right) | ||
@@ -572,6 +573,2 @@ if (o.originOf != null && o.originOf.length > 0) { | ||
// right should be in o.originOf => it is set it the previous for loop | ||
} else { | ||
// we didn't need to reset the origin of right | ||
// so we have to set right here | ||
yield* this.setOperation(right) | ||
} | ||
@@ -578,0 +575,0 @@ } |
169
src/Utils.js
@@ -95,2 +95,149 @@ /* @flow */ | ||
this.onevent(op) | ||
} else if (op.struct === 'Delete') { | ||
var self = this | ||
var checkDelete = function checkDelete (d) { | ||
if (d.length == null) { | ||
throw new Error('This shouldn\'t happen! d.length must be defined!') | ||
} | ||
// we check if o deletes something in self.waiting | ||
// if so, we remove the deleted operation | ||
for (var w = 0; w < self.waiting.length; w++) { | ||
var i = self.waiting[w] | ||
if (i.struct === 'Insert' && i.id[0] === d.target[0]) { | ||
var iLength = i.hasOwnProperty('content') ? i.content.length : 1 | ||
var dStart = d.target[1] | ||
var dEnd = d.target[1] + (d.length || 1) | ||
var iStart = i.id[1] | ||
var iEnd = i.id[1] + iLength | ||
// Check if they don't overlap | ||
if (iEnd <= dStart || dEnd <= iStart) { | ||
// no overlapping | ||
continue | ||
} | ||
// we check all overlapping cases. All cases: | ||
/* | ||
1) iiiii | ||
ddddd | ||
--> modify i and d | ||
2) iiiiiii | ||
ddddd | ||
--> modify i, remove d | ||
3) iiiiiii | ||
ddd | ||
--> remove d, modify i, and create another i (for the right hand side) | ||
4) iiiii | ||
ddddddd | ||
--> remove i, modify d | ||
5) iiiiiii | ||
ddddddd | ||
--> remove both i and d (**) | ||
6) iiiiiii | ||
ddddd | ||
--> modify i, remove d | ||
7) iii | ||
ddddddd | ||
--> remove i, create and apply two d with checkDelete(d) (**) | ||
8) iiiii | ||
ddddddd | ||
--> remove i, modify d (**) | ||
9) iiiii | ||
ddddd | ||
--> modify i and d | ||
(**) (also check if i contains content or type) | ||
*/ | ||
// TODO: I left some debugger statements, because I want to debug all cases once in production. REMEMBER END TODO | ||
if (iStart < dStart) { | ||
if (dStart < iEnd) { | ||
if (iEnd < dEnd) { | ||
// Case 1 | ||
// remove the right part of i's content | ||
i.content.splice(dStart - iStart) | ||
// remove the start of d's deletion | ||
d.length = dEnd - iEnd | ||
d.target = [d.target[0], iEnd] | ||
continue | ||
} else if (iEnd === dEnd) { | ||
// Case 2 | ||
i.content.splice(dStart - iStart) | ||
// remove d, we do that by simply ending this function | ||
return | ||
} else { // (dEnd < iEnd) | ||
// Case 3 | ||
var newI = { | ||
id: [i.id[0], dEnd], | ||
content: i.content.slice(dEnd - iStart), | ||
struct: 'Insert' | ||
} | ||
self.waiting.push(newI) | ||
i.content.splice(dStart - iStart) | ||
return | ||
} | ||
} | ||
} else if (dStart === iStart) { | ||
if (iEnd < dEnd) { | ||
// Case 4 | ||
d.length = dEnd - iEnd | ||
d.target = [d.target[0], iEnd] | ||
i.content = [] | ||
continue | ||
} else if (iEnd === dEnd) { | ||
// Case 5 | ||
self.waiting.splice(w, 1) | ||
return | ||
} else { // (dEnd < iEnd) | ||
// Case 6 | ||
i.content = i.content.slice(dEnd - iStart) | ||
i.id = [i.id[0], dEnd] | ||
return | ||
} | ||
} else { // (dStart < iStart) | ||
if (iStart < dEnd) { | ||
// they overlap | ||
/* | ||
7) iii | ||
ddddddd | ||
--> remove i, create and apply two d with checkDelete(d) (**) | ||
8) iiiii | ||
ddddddd | ||
--> remove i, modify d (**) | ||
9) iiiii | ||
ddddd | ||
--> modify i and d | ||
*/ | ||
if (iEnd < dEnd) { | ||
// Case 7 | ||
// debugger // TODO: You did not test this case yet!!!! (add the debugger here) | ||
self.waiting.splice(w, 1) | ||
checkDelete({ | ||
target: [d.target[0], dStart], | ||
length: iStart - dStart, | ||
struct: 'Delete' | ||
}) | ||
checkDelete({ | ||
target: [d.target[0], iEnd], | ||
length: iEnd - dEnd, | ||
struct: 'Delete' | ||
}) | ||
return | ||
} else if (iEnd === dEnd) { | ||
// Case 8 | ||
self.waiting.splice(w, 1) | ||
w-- | ||
d.length -= iLength | ||
continue | ||
} else { // dEnd < iEnd | ||
// Case 9 | ||
d.length = iStart - dStart | ||
i.content.splice(0, dEnd - iStart) | ||
i.id = [i.id[0], dEnd] | ||
continue | ||
} | ||
} | ||
} | ||
} | ||
} | ||
// finished with remaining operations | ||
self.waiting.push(d) | ||
} | ||
checkDelete(op) | ||
} else { | ||
@@ -180,7 +327,23 @@ this.waiting.push(op) | ||
}) | ||
this.waiting = [] | ||
// put in executable order | ||
ins = notSoSmartSort(ins) | ||
ins.forEach(this.onevent) | ||
dels.forEach(this.onevent) | ||
this.waiting = [] | ||
// this.onevent can trigger the creation of another operation | ||
// -> check if this.awaiting increased & stop computation if it does | ||
for (var i = 0; i < ins.length; i++) { | ||
if (this.awaiting === 0) { | ||
this.onevent(ins[i]) | ||
} else { | ||
this.waiting = this.waiting.concat(ins.slice(i)) | ||
break | ||
} | ||
} | ||
for (i = 0; i < dels.length; i++) { | ||
if (this.awaiting === 0) { | ||
this.onevent(dels[i]) | ||
} else { | ||
this.waiting = this.waiting.concat(dels.slice(i)) | ||
break | ||
} | ||
} | ||
} | ||
@@ -187,0 +350,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
800949
5155
32