change client id when duplicate content is detected
This commit is contained in:
parent
b399ffa765
commit
9f5bc9ddfe
@ -47,6 +47,7 @@ export {
|
|||||||
typeMapGetSnapshot,
|
typeMapGetSnapshot,
|
||||||
iterateDeletedStructs,
|
iterateDeletedStructs,
|
||||||
applyUpdate,
|
applyUpdate,
|
||||||
|
readUpdate,
|
||||||
encodeStateAsUpdate,
|
encodeStateAsUpdate,
|
||||||
encodeStateVector,
|
encodeStateVector,
|
||||||
UndoManager,
|
UndoManager,
|
||||||
|
@ -17,6 +17,8 @@ import { Observable } from 'lib0/observable.js'
|
|||||||
import * as random from 'lib0/random.js'
|
import * as random from 'lib0/random.js'
|
||||||
import * as map from 'lib0/map.js'
|
import * as map from 'lib0/map.js'
|
||||||
|
|
||||||
|
export const generateNewClientId = random.uint32
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Yjs instance handles the state of shared data.
|
* A Yjs instance handles the state of shared data.
|
||||||
* @extends Observable<string>
|
* @extends Observable<string>
|
||||||
@ -31,7 +33,7 @@ export class Doc extends Observable {
|
|||||||
super()
|
super()
|
||||||
this.gc = gc
|
this.gc = gc
|
||||||
this.gcFilter = gcFilter
|
this.gcFilter = gcFilter
|
||||||
this.clientID = random.uint32()
|
this.clientID = generateNewClientId()
|
||||||
/**
|
/**
|
||||||
* @type {Map<string, AbstractType<YEvent>>}
|
* @type {Map<string, AbstractType<YEvent>>}
|
||||||
*/
|
*/
|
||||||
|
@ -10,6 +10,7 @@ import {
|
|||||||
findIndexSS,
|
findIndexSS,
|
||||||
callEventHandlerListeners,
|
callEventHandlerListeners,
|
||||||
Item,
|
Item,
|
||||||
|
generateNewClientId,
|
||||||
StructStore, ID, AbstractType, AbstractStruct, YEvent, Doc // eslint-disable-line
|
StructStore, ID, AbstractType, AbstractStruct, YEvent, Doc // eslint-disable-line
|
||||||
} from '../internals.js'
|
} from '../internals.js'
|
||||||
|
|
||||||
@ -17,6 +18,7 @@ import * as encoding from 'lib0/encoding.js'
|
|||||||
import * as map from 'lib0/map.js'
|
import * as map from 'lib0/map.js'
|
||||||
import * as math from 'lib0/math.js'
|
import * as math from 'lib0/math.js'
|
||||||
import * as set from 'lib0/set.js'
|
import * as set from 'lib0/set.js'
|
||||||
|
import * as logging from 'lib0/logging.js'
|
||||||
import { callAll } from 'lib0/function.js'
|
import { callAll } from 'lib0/function.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -313,6 +315,10 @@ const cleanupTransactions = (transactionCleanups, i) => {
|
|||||||
tryToMergeWithLeft(structs, replacedStructPos)
|
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
|
// @todo Merge all the transactions into one and provide send the data as a single update message
|
||||||
doc.emit('afterTransactionCleanup', [transaction, doc])
|
doc.emit('afterTransactionCleanup', [transaction, doc])
|
||||||
if (doc._observers.has('update')) {
|
if (doc._observers.has('update')) {
|
||||||
|
19
tests/consistency.tests.js
Normal file
19
tests/consistency.tests.js
Normal 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)
|
||||||
|
}
|
@ -5,6 +5,7 @@ import * as text from './y-text.tests.js'
|
|||||||
import * as xml from './y-xml.tests.js'
|
import * as xml from './y-xml.tests.js'
|
||||||
import * as encoding from './encoding.tests.js'
|
import * as encoding from './encoding.tests.js'
|
||||||
import * as undoredo from './undo-redo.tests.js'
|
import * as undoredo from './undo-redo.tests.js'
|
||||||
|
import * as consistency from './consistency.tests.js'
|
||||||
|
|
||||||
import { runTests } from 'lib0/testing.js'
|
import { runTests } from 'lib0/testing.js'
|
||||||
import { isBrowser, isNode } from 'lib0/environment.js'
|
import { isBrowser, isNode } from 'lib0/environment.js'
|
||||||
@ -14,7 +15,7 @@ if (isBrowser) {
|
|||||||
log.createVConsole(document.body)
|
log.createVConsole(document.body)
|
||||||
}
|
}
|
||||||
runTests({
|
runTests({
|
||||||
map, array, text, xml, encoding, undoredo
|
map, array, text, xml, consistency, encoding, undoredo
|
||||||
}).then(success => {
|
}).then(success => {
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
if (isNode) {
|
if (isNode) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user