Deploy 12.2.0

This commit is contained in:
Kevin Jahns 2017-05-03 16:17:06 +02:00
parent 3eafd78710
commit c3d21b5c8e
6 changed files with 119 additions and 8066 deletions

View File

@ -170,6 +170,11 @@ soon, if possible.
immediately going to be resolved, without waiting for any confirmation from immediately going to be resolved, without waiting for any confirmation from
the server. Use with caution. the server. Use with caution.
* Have a look at the used connector repository to see all available options. * Have a look at the used connector repository to see all available options.
* *Only if you know what you are doing:* Set
`options.connector.preferUntransformed = true` in order receive the shared
data untransformed. This is very efficient as the database content is simply
copied to this client. This does only work if this client receives content
from only one client.
* options.sourceDir (browser only) * options.sourceDir (browser only)
* Path where all y-* modules are stored * Path where all y-* modules are stored
* Defaults to `/bower_components` * Defaults to `/bower_components`

View File

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

137
y.es6
View File

@ -338,7 +338,7 @@ function enable(namespaces) {
exports.names = []; exports.names = [];
exports.skips = []; exports.skips = [];
var split = (namespaces || '').split(/[\s,]+/); var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
var len = split.length; var len = split.length;
for (var i = 0; i < len; i++) { for (var i = 0; i < len; i++) {
@ -417,7 +417,7 @@ var y = d * 365.25
* - `long` verbose formatting [false] * - `long` verbose formatting [false]
* *
* @param {String|Number} val * @param {String|Number} val
* @param {Object} options * @param {Object} [options]
* @throws {Error} throw an error if val is not a non-empty string or a number * @throws {Error} throw an error if val is not a non-empty string or a number
* @return {String|Number} * @return {String|Number}
* @api public * @api public
@ -720,6 +720,10 @@ process.off = noop;
process.removeListener = noop; process.removeListener = noop;
process.removeAllListeners = noop; process.removeAllListeners = noop;
process.emit = noop; process.emit = noop;
process.prependListener = noop;
process.prependOnceListener = noop;
process.listeners = function (name) { return [] }
process.binding = function (name) { process.binding = function (name) {
throw new Error('process.binding is not supported'); throw new Error('process.binding is not supported');
@ -751,7 +755,6 @@ module.exports = function (Y/* :any */) {
syncingClients: Array<UserId>; syncingClients: Array<UserId>;
forwardToSyncingClients: boolean; forwardToSyncingClients: boolean;
debug: boolean; debug: boolean;
broadcastedHB: boolean;
syncStep2: Promise; syncStep2: Promise;
userId: UserId; userId: UserId;
send: Function; send: Function;
@ -770,6 +773,11 @@ module.exports = function (Y/* :any */) {
if (opts == null) { if (opts == null) {
opts = {} opts = {}
} }
// Prefer to receive untransformed operations. This does only work if
// this client receives operations from only one other client.
// In particular, this does not work with y-webrtc.
// It will work with y-websockets-client
this.preferUntransformed = opts.preferUntransformed || false
if (opts.role == null || opts.role === 'master') { if (opts.role == null || opts.role === 'master') {
this.role = 'master' this.role = 'master'
} else if (opts.role === 'slave') { } else if (opts.role === 'slave') {
@ -789,7 +797,6 @@ module.exports = function (Y/* :any */) {
this.syncingClients = [] this.syncingClients = []
this.forwardToSyncingClients = opts.forwardToSyncingClients !== false this.forwardToSyncingClients = opts.forwardToSyncingClients !== false
this.debug = opts.debug === true this.debug = opts.debug === true
this.broadcastedHB = false
this.syncStep2 = Promise.resolve() this.syncStep2 = Promise.resolve()
this.broadcastOpBuffer = [] this.broadcastOpBuffer = []
this.protocolVersion = 11 this.protocolVersion = 11
@ -810,13 +817,13 @@ module.exports = function (Y/* :any */) {
} }
reconnect () { reconnect () {
this.log('reconnecting..') this.log('reconnecting..')
this.y.db.startGarbageCollector()
} }
disconnect () { disconnect () {
this.log('discronnecting..') this.log('discronnecting..')
this.connections = {} this.connections = {}
this.isSynced = false this.isSynced = false
this.currentSyncTarget = null this.currentSyncTarget = null
this.broadcastedHB = false
this.syncingClients = [] this.syncingClients = []
this.whenSyncedListeners = [] this.whenSyncedListeners = []
return this.y.db.stopGarbageCollector() return this.y.db.stopGarbageCollector()
@ -828,7 +835,6 @@ module.exports = function (Y/* :any */) {
} }
this.isSynced = false this.isSynced = false
this.currentSyncTarget = null this.currentSyncTarget = null
this.broadcastedHB = false
this.findNextSyncTarget() this.findNextSyncTarget()
} }
setUserId (userId) { setUserId (userId) {
@ -915,13 +921,17 @@ module.exports = function (Y/* :any */) {
this.y.db.requestTransaction(function *() { this.y.db.requestTransaction(function *() {
var stateSet = yield* this.getStateSet() var stateSet = yield* this.getStateSet()
var deleteSet = yield* this.getDeleteSet() var deleteSet = yield* this.getDeleteSet()
conn.send(syncUser, { var answer = {
type: 'sync step 1', type: 'sync step 1',
stateSet: stateSet, stateSet: stateSet,
deleteSet: deleteSet, deleteSet: deleteSet,
protocolVersion: conn.protocolVersion, protocolVersion: conn.protocolVersion,
auth: conn.authInfo auth: conn.authInfo
}) }
if (conn.preferUntransformed && Object.keys(stateSet).length === 0) {
answer.preferUntransformed = true
}
conn.send(syncUser, answer)
}) })
} else { } else {
if (!conn.isSynced) { if (!conn.isSynced) {
@ -1027,15 +1037,19 @@ module.exports = function (Y/* :any */) {
} }
var ds = yield* this.getDeleteSet() var ds = yield* this.getDeleteSet()
var ops = yield* this.getOperations(m.stateSet) var answer = {
conn.send(sender, {
type: 'sync step 2', type: 'sync step 2',
os: ops,
stateSet: currentStateSet, stateSet: currentStateSet,
deleteSet: ds, deleteSet: ds,
protocolVersion: this.protocolVersion, protocolVersion: this.protocolVersion,
auth: this.authInfo auth: this.authInfo
}) }
if (message.preferUntransformed === true && Object.keys(m.stateSet).length === 0) {
answer.osUntransformed = yield* this.getOperationsUntransformed()
} else {
answer.os = yield* this.getOperations(m.stateSet)
}
conn.send(sender, answer)
if (this.forwardToSyncingClients) { if (this.forwardToSyncingClients) {
conn.syncingClients.push(sender) conn.syncingClients.push(sender)
setTimeout(function () { setTimeout(function () {
@ -1053,9 +1067,6 @@ module.exports = function (Y/* :any */) {
} }
}) })
} else if (message.type === 'sync step 2' && canWrite(auth)) { } else if (message.type === 'sync step 2' && canWrite(auth)) {
let conn = this
var broadcastHB = !this.broadcastedHB
this.broadcastedHB = true
var db = this.y.db var db = this.y.db
var defer = {} var defer = {}
defer.promise = new Promise(function (resolve) { defer.promise = new Promise(function (resolve) {
@ -1065,7 +1076,15 @@ module.exports = function (Y/* :any */) {
let m /* :MessageSyncStep2 */ = message let m /* :MessageSyncStep2 */ = message
db.requestTransaction(function * () { db.requestTransaction(function * () {
yield* this.applyDeleteSet(m.deleteSet) yield* this.applyDeleteSet(m.deleteSet)
this.store.apply(m.os) if (m.osUntransformed != null) {
yield* this.applyOperationsUntransformed(m.osUntransformed, m.stateSet)
} else {
this.store.apply(m.os)
}
/*
* This just sends the complete hb after some time
* Mostly for debugging..
*
db.requestTransaction(function * () { db.requestTransaction(function * () {
var ops = yield* this.getOperations(m.stateSet) var ops = yield* this.getOperations(m.stateSet)
if (ops.length > 0) { if (ops.length > 0) {
@ -1079,8 +1098,9 @@ module.exports = function (Y/* :any */) {
conn.broadcastOps(ops) conn.broadcastOps(ops)
} }
} }
defer.resolve()
}) })
*/
defer.resolve()
}) })
} else if (message.type === 'sync done') { } else if (message.type === 'sync done') {
var self = this var self = this
@ -1252,7 +1272,7 @@ module.exports = function (Y) {
ps.push(self.users[name].y.db.whenTransactionsFinished()) ps.push(self.users[name].y.db.whenTransactionsFinished())
} }
Promise.all(ps).then(resolve, reject) Promise.all(ps).then(resolve, reject)
}, 0) }, 10)
}) })
}, },
flushOne: function flushOne () { flushOne: function flushOne () {
@ -1362,11 +1382,15 @@ module.exports = function (Y) {
return Y.utils.globalRoom.flushAll() return Y.utils.globalRoom.flushAll()
} }
disconnect () { disconnect () {
var waitForMe = Promise.resolve()
if (!this.isDisconnected()) { if (!this.isDisconnected()) {
globalRoom.removeUser(this.userId) globalRoom.removeUser(this.userId)
super.disconnect() waitForMe = super.disconnect()
} }
return this.y.db.whenTransactionsFinished() var self = this
return waitForMe.then(function () {
return self.y.db.whenTransactionsFinished()
})
} }
flush () { flush () {
var self = this var self = this
@ -1430,6 +1454,7 @@ module.exports = function (Y /* :any */) {
*/ */
constructor (y, opts) { constructor (y, opts) {
this.y = y this.y = y
this.dbOpts = opts
var os = this var os = this
this.userId = null this.userId = null
var resolve var resolve
@ -1466,12 +1491,6 @@ module.exports = function (Y /* :any */) {
} }
this.gc1 = [] // first stage this.gc1 = [] // first stage
this.gc2 = [] // second stage -> after that, remove the op this.gc2 = [] // second stage -> after that, remove the op
this.gc = opts.gc == null || opts.gc
if (this.gc) {
this.gcTimeout = !opts.gcTimeout ? 50000 : opts.gcTimeout
} else {
this.gcTimeout = -1
}
function garbageCollect () { function garbageCollect () {
return os.whenTransactionsFinished().then(function () { return os.whenTransactionsFinished().then(function () {
@ -1506,13 +1525,23 @@ module.exports = function (Y /* :any */) {
}) })
} }
this.garbageCollect = garbageCollect this.garbageCollect = garbageCollect
if (this.gcTimeout > 0) { this.startGarbageCollector()
garbageCollect()
}
this.repairCheckInterval = !opts.repairCheckInterval ? 6000 : opts.repairCheckInterval this.repairCheckInterval = !opts.repairCheckInterval ? 6000 : opts.repairCheckInterval
this.opsReceivedTimestamp = new Date() this.opsReceivedTimestamp = new Date()
this.startRepairCheck() this.startRepairCheck()
} }
startGarbageCollector () {
this.gc = this.dbOpts.gc == null || this.dbOpts.gc
if (this.gc) {
this.gcTimeout = !this.dbOpts.gcTimeout ? 50000 : this.dbOpts.gcTimeout
} else {
this.gcTimeout = -1
}
if (this.gcTimeout > 0) {
this.garbageCollect()
}
}
startRepairCheck () { startRepairCheck () {
var os = this var os = this
if (this.repairCheckInterval > 0) { if (this.repairCheckInterval > 0) {
@ -3421,6 +3450,56 @@ module.exports = function (Y/* :any */) {
} }
return send.reverse() return send.reverse()
} }
/*
* Get the plain untransformed operations from the database.
* You can apply these operations using .applyOperationsUntransformed(ops)
*
*/
* getOperationsUntransformed () {
var ops = []
yield* this.os.iterate(this, null, null, function * (op) {
if (op.id[0] !== '_') {
ops.push(Y.Struct[op.struct].encode(op))
}
})
return {
untransformed: ops
}
}
* applyOperationsUntransformed (m, stateSet) {
var ops = m.untransformed
for (var i = 0; i < ops.length; i++) {
var op = ops[i]
// create, and modify parent, if it is created implicitly
if (op.parent != null && op.parent[0] === '_') {
if (op.struct === 'Insert') {
// update parents .map/start/end properties
if (op.parentSub != null && op.left == null) {
// op is child of Map
let parent = yield* this.getOperation(op.parent)
parent.map[op.parentSub] = op.id
yield* this.setOperation(parent)
} else if (op.right == null || op.left == null) {
let parent = yield* this.getOperation(op.parent)
if (op.right == null) {
parent.end = Y.utils.getLastId(op)
}
if (op.left == null) {
parent.start = op.id
}
yield* this.setOperation(parent)
}
}
}
yield* this.os.put(op)
}
for (var user in stateSet) {
yield* this.ss.put({
id: [user],
clock: stateSet[user]
})
}
}
/* this is what we used before.. use this as a reference.. /* this is what we used before.. use this as a reference..
* makeOperationReady (startSS, op) { * makeOperationReady (startSS, op) {
op = Y.Struct[op.struct].encode(op) op = Y.Struct[op.struct].encode(op)

File diff suppressed because one or more lines are too long

8037
y.js

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long