change client id when duplicate content is detected

This commit is contained in:
Kevin Jahns 2020-05-03 16:10:58 +02:00
parent b399ffa765
commit 9f5bc9ddfe
5 changed files with 31 additions and 2 deletions

View File

@ -47,6 +47,7 @@ export {
typeMapGetSnapshot,
iterateDeletedStructs,
applyUpdate,
readUpdate,
encodeStateAsUpdate,
encodeStateVector,
UndoManager,

View File

@ -17,6 +17,8 @@ import { Observable } from 'lib0/observable.js'
import * as random from 'lib0/random.js'
import * as map from 'lib0/map.js'
export const generateNewClientId = random.uint32
/**
* A Yjs instance handles the state of shared data.
* @extends Observable<string>
@ -31,7 +33,7 @@ export class Doc extends Observable {
super()
this.gc = gc
this.gcFilter = gcFilter
this.clientID = random.uint32()
this.clientID = generateNewClientId()
/**
* @type {Map<string, AbstractType<YEvent>>}
*/

View File

@ -10,6 +10,7 @@ import {
findIndexSS,
callEventHandlerListeners,
Item,
generateNewClientId,
StructStore, ID, AbstractType, AbstractStruct, YEvent, Doc // eslint-disable-line
} from '../internals.js'
@ -17,6 +18,7 @@ import * as encoding from 'lib0/encoding.js'
import * as map from 'lib0/map.js'
import * as math from 'lib0/math.js'
import * as set from 'lib0/set.js'
import * as logging from 'lib0/logging.js'
import { callAll } from 'lib0/function.js'
/**
@ -313,6 +315,10 @@ const cleanupTransactions = (transactionCleanups, i) => {
tryToMergeWithLeft(structs, replacedStructPos)
}
}
if (!transaction.local && transaction.afterState.get(doc.clientID) !== transaction.beforeState.get(doc.clientID)) {
doc.clientID = generateNewClientId()
logging.print(logging.ORANGE, logging.BOLD, '[yjs] ', logging.UNBOLD, logging.RED, 'Changed the client-id because another client seems to be using it.')
}
// @todo Merge all the transactions into one and provide send the data as a single update message
doc.emit('afterTransactionCleanup', [transaction, doc])
if (doc._observers.has('update')) {

View File

@ -0,0 +1,19 @@
import * as Y from '../src/index.js'
import * as t from 'lib0/testing.js'
/**
* Client id should be changed when an instance receives updates from another client using the same client id.
*
* @param {t.TestCase} tc
*/
export const testClientIdDuplicateChange = tc => {
const doc1 = new Y.Doc()
doc1.clientID = 0
const doc2 = new Y.Doc()
doc2.clientID = 0
t.assert(doc2.clientID === doc1.clientID)
doc1.getArray('a').insert(0, [1, 2])
Y.applyUpdate(doc2, Y.encodeStateAsUpdate(doc1))
t.assert(doc2.clientID !== doc1.clientID)
}

View File

@ -5,6 +5,7 @@ import * as text from './y-text.tests.js'
import * as xml from './y-xml.tests.js'
import * as encoding from './encoding.tests.js'
import * as undoredo from './undo-redo.tests.js'
import * as consistency from './consistency.tests.js'
import { runTests } from 'lib0/testing.js'
import { isBrowser, isNode } from 'lib0/environment.js'
@ -14,7 +15,7 @@ if (isBrowser) {
log.createVConsole(document.body)
}
runTests({
map, array, text, xml, encoding, undoredo
map, array, text, xml, consistency, encoding, undoredo
}).then(success => {
/* istanbul ignore next */
if (isNode) {