Compare commits

...

4 Commits

Author SHA1 Message Date
Kevin Jahns
3b8e148d8f Deploy 0.8.3 2016-01-15 03:46:51 +01:00
Kevin Jahns
a77eb39218 Deploy 0.8.2 2016-01-15 03:10:52 +01:00
Kevin Jahns
9902da470b Deploy 0.8.1 2016-01-15 00:03:37 +01:00
Kevin Jahns
0ec83aa431 Deploy 0.8.0 2016-01-15 00:01:56 +01:00
7 changed files with 110 additions and 37 deletions

2
.gitignore vendored
View File

@@ -1,5 +1,5 @@
node_modules
Examples/bower_components
bower_components
.directory
.codio
.settings

View File

@@ -9,7 +9,15 @@
"license": "MIT",
"ignore": [],
"dependencies": {
"yjs": "../",
"y-webrtc": "~0.6.4"
"yjs": "~0.7.6",
"y-array": "~0.7.5",
"y-map": "~0.7.2",
"y-memory": "~0.7.0",
"y-richtext": "~0.7.5",
"y-webrtc": "~0.7.1",
"y-websockets-client": "~0.7.10",
"y-text": "~0.7.1",
"y-indexeddb": "~0.7.1",
"quill": "~0.20.1"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "yjs",
"version": "0.7.7",
"version": "0.8.4",
"homepage": "y-js.org",
"authors": [
"Kevin Jahns <kevin.jahns@rwth-aachen.de>"

123
y.es6
View File

@@ -1909,34 +1909,8 @@ module.exports = function (Y/* :any */) {
})
return ss
}
* getOperations (startSS) {
// TODO: use bounds here!
if (startSS == null) {
startSS = {}
}
var ops = []
var endSV = yield* this.getStateVector()
for (var endState of endSV) {
var user = endState.user
if (user === '_') {
continue
}
var startPos = startSS[user] || 0
yield* this.os.iterate(this, [user, startPos], [user, Number.MAX_VALUE], function * (op) {
ops.push(op)
})
}
var res = []
for (var op of ops) {
var o = yield* this.makeOperationReady(startSS, op)
res.push(o)
}
return res
}
/*
Here, we make op executable for the receiving user.
Here, we make all missing operations executable for the receiving user.
Notes:
startSS: denotes to the SV that the remote user sent
@@ -1971,7 +1945,92 @@ module.exports = function (Y/* :any */) {
(startSS or currSS.. ?)
-> Could be necessary when I turn GC again.
-> Is a bad(ish) idea because it requires more computation
What we do:
* Iterate over all missing operations.
* When there is an operation, where the right op is known, send this op all missing ops to the left to the user
* I explained above what we have to do with each operation. Here is how we do it efficiently:
1. Go to the left until you find either op.origin, or a known operation (let o denote current operation in the iteration)
2. Found a known operation -> set op.left = o, and send it to the user. stop
3. Found o = op.origin -> set op.left = op.origin, and send it to the user. start again from 1. (set op = o)
4. Found some o -> set o.right = op, o.left = o.origin, send it to the user, continue
*/
* getOperations (startSS) {
// TODO: use bounds here!
if (startSS == null) {
startSS = {}
}
var send = []
var endSV = yield* this.getStateVector()
for (var endState of endSV) {
var user = endState.user
if (user === '_') {
continue
}
var startPos = startSS[user] || 0
yield* this.os.iterate(this, [user, startPos], [user, Number.MAX_VALUE], function * (op) {
op = Y.Struct[op.struct].encode(op)
if (op.struct !== 'Insert') {
send.push(op)
} else if (op.right == null || op.right[1] < (startSS[op.right[0]] || 0)) {
// case 1. op.right is known
var o = op
// Remember: ?
// -> set op.right
// 1. to the first operation that is known (according to startSS)
// 2. or to the first operation that has an origin that is not to the
// right of op.
// For this we maintain a list of ops which origins are not found yet.
var missing_origins = [op]
var newright = op.right
while (true) {
if (o.left == null) {
op.left = null
send.push(op)
if (!Y.utils.compareIds(o.id, op.id)) {
o = Y.Struct[op.struct].encode(o)
o.right = missing_origins[missing_origins.length - 1].id
send.push(o)
}
break
}
o = yield* this.getOperation(o.left)
// we set another o, check if we can reduce $missing_origins
while (missing_origins.length > 0 && Y.utils.compareIds(missing_origins[missing_origins.length - 1].origin, o.id)) {
missing_origins.pop()
}
if (o.id[1] < (startSS[o.id[0]] || 0)) {
// case 2. o is known
op.left = o.id
send.push(op)
break
} else if (Y.utils.compareIds(o.id, op.origin)) {
// case 3. o is op.origin
op.left = op.origin
send.push(op)
op = Y.Struct[op.struct].encode(o)
op.right = newright
if (missing_origins.length > 0) {
console.log('This should not happen .. :( please report this')
}
missing_origins = [op]
} else {
// case 4. send o, continue to find op.origin
var s = Y.Struct[op.struct].encode(o)
s.right = missing_origins[missing_origins.length - 1].id
s.left = s.origin
send.push(s)
missing_origins.push(o)
}
}
}
})
}
return send.reverse()
}
/* this is what we used before.. use this as a reference..
* makeOperationReady (startSS, op) {
op = Y.Struct[op.struct].encode(op)
op = Y.utils.copyObject(op)
@@ -1995,6 +2054,7 @@ module.exports = function (Y/* :any */) {
op.left = op.origin
return op
}
*/
}
Y.Transaction = TransactionInterface
}
@@ -2325,8 +2385,9 @@ function Y (opts/* :YOptions */) /* :Promise<YConfig> */ {
Y.sourceDir = opts.sourceDir
return Y.requestModules(modules).then(function () {
return new Promise(function (resolve) {
var yconfig = new YConfig(opts, function () {
yconfig.db.whenUserIdSet(function () {
var yconfig = new YConfig(opts)
yconfig.db.whenUserIdSet(function () {
yconfig.init(function () {
resolve(yconfig)
})
})
@@ -2343,6 +2404,10 @@ class YConfig {
constructor (opts, callback) {
this.db = new Y[opts.db.name](this, opts.db)
this.connector = new Y[opts.connector.name](this, opts.connector)
this.options = opts
}
init (callback) {
var opts = this.options
var share = {}
this.share = share
this.db.requestTransaction(function * requestTransaction () {

File diff suppressed because one or more lines are too long

4
y.js

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long