Include Item.redone
in binary encoding
This commit is contained in:
parent
384ec4db78
commit
1cfc865045
@ -93,6 +93,7 @@ export const splitItem = (transaction, leftItem, diff) => {
|
|||||||
leftItem.rightOrigin,
|
leftItem.rightOrigin,
|
||||||
leftItem.parent,
|
leftItem.parent,
|
||||||
leftItem.parentSub,
|
leftItem.parentSub,
|
||||||
|
leftItem.redone !== null ? createID(leftItem.redone.client, leftItem.redone.clock + diff) : null,
|
||||||
leftItem.content.splice(diff)
|
leftItem.content.splice(diff)
|
||||||
)
|
)
|
||||||
if (leftItem.deleted) {
|
if (leftItem.deleted) {
|
||||||
@ -101,9 +102,6 @@ export const splitItem = (transaction, leftItem, diff) => {
|
|||||||
if (leftItem.keep) {
|
if (leftItem.keep) {
|
||||||
rightItem.keep = true
|
rightItem.keep = true
|
||||||
}
|
}
|
||||||
if (leftItem.redone !== null) {
|
|
||||||
rightItem.redone = createID(leftItem.redone.client, leftItem.redone.clock + diff)
|
|
||||||
}
|
|
||||||
// update left (do not set leftItem.rightOrigin as it will lead to problems when syncing)
|
// update left (do not set leftItem.rightOrigin as it will lead to problems when syncing)
|
||||||
leftItem.right = rightItem
|
leftItem.right = rightItem
|
||||||
// update right
|
// update right
|
||||||
@ -232,6 +230,7 @@ export const redoItem = (transaction, item, redoitems, itemsToDelete, ignoreRemo
|
|||||||
right, right && right.id,
|
right, right && right.id,
|
||||||
parentType,
|
parentType,
|
||||||
item.parentSub,
|
item.parentSub,
|
||||||
|
null,
|
||||||
item.content.copy()
|
item.content.copy()
|
||||||
)
|
)
|
||||||
item.redone = nextId
|
item.redone = nextId
|
||||||
@ -252,9 +251,10 @@ export class Item extends AbstractStruct {
|
|||||||
* @param {ID | null} rightOrigin
|
* @param {ID | null} rightOrigin
|
||||||
* @param {AbstractType<any>|ID|null} parent Is a type if integrated, is null if it is possible to copy parent from left or right, is ID before integration to search for it.
|
* @param {AbstractType<any>|ID|null} parent Is a type if integrated, is null if it is possible to copy parent from left or right, is ID before integration to search for it.
|
||||||
* @param {string | null} parentSub
|
* @param {string | null} parentSub
|
||||||
|
* @param {ID | null} redone
|
||||||
* @param {AbstractContent} content
|
* @param {AbstractContent} content
|
||||||
*/
|
*/
|
||||||
constructor (id, left, origin, right, rightOrigin, parent, parentSub, content) {
|
constructor (id, left, origin, right, rightOrigin, parent, parentSub, redone, content) {
|
||||||
super(id, content.getLength())
|
super(id, content.getLength())
|
||||||
/**
|
/**
|
||||||
* The item that was originally to the left of this item.
|
* The item that was originally to the left of this item.
|
||||||
@ -293,7 +293,7 @@ export class Item extends AbstractStruct {
|
|||||||
* this operation.
|
* this operation.
|
||||||
* @type {ID | null}
|
* @type {ID | null}
|
||||||
*/
|
*/
|
||||||
this.redone = null
|
this.redone = redone
|
||||||
/**
|
/**
|
||||||
* @type {AbstractContent}
|
* @type {AbstractContent}
|
||||||
*/
|
*/
|
||||||
@ -653,10 +653,11 @@ export class Item extends AbstractStruct {
|
|||||||
const origin = offset > 0 ? createID(this.id.client, this.id.clock + offset - 1) : this.origin
|
const origin = offset > 0 ? createID(this.id.client, this.id.clock + offset - 1) : this.origin
|
||||||
const rightOrigin = this.rightOrigin
|
const rightOrigin = this.rightOrigin
|
||||||
const parentSub = this.parentSub
|
const parentSub = this.parentSub
|
||||||
const info = (this.content.getRef() & binary.BITS5) |
|
const info = (this.content.getRef() & binary.BITS4) |
|
||||||
(origin === null ? 0 : binary.BIT8) | // origin is defined
|
(origin === null ? 0 : binary.BIT8) | // origin is defined
|
||||||
(rightOrigin === null ? 0 : binary.BIT7) | // right origin is defined
|
(rightOrigin === null ? 0 : binary.BIT7) | // right origin is defined
|
||||||
(parentSub === null ? 0 : binary.BIT6) // parentSub is non-null
|
(parentSub === null ? 0 : binary.BIT6) | // parentSub is non-null
|
||||||
|
(this.redone === null ? 0 : binary.BIT5) // redone is defined
|
||||||
encoder.writeInfo(info)
|
encoder.writeInfo(info)
|
||||||
if (origin !== null) {
|
if (origin !== null) {
|
||||||
encoder.writeLeftID(origin)
|
encoder.writeLeftID(origin)
|
||||||
@ -691,6 +692,9 @@ export class Item extends AbstractStruct {
|
|||||||
encoder.writeString(parentSub)
|
encoder.writeString(parentSub)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this.redone !== null) {
|
||||||
|
encoder.writeRedone(this.redone)
|
||||||
|
}
|
||||||
this.content.write(encoder, offset)
|
this.content.write(encoder, offset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -699,7 +703,7 @@ export class Item extends AbstractStruct {
|
|||||||
* @param {UpdateDecoderV1 | UpdateDecoderV2} decoder
|
* @param {UpdateDecoderV1 | UpdateDecoderV2} decoder
|
||||||
* @param {number} info
|
* @param {number} info
|
||||||
*/
|
*/
|
||||||
export const readItemContent = (decoder, info) => contentRefs[info & binary.BITS5](decoder)
|
export const readItemContent = (decoder, info) => contentRefs[info & binary.BITS4](decoder)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A lookup map for reading Item content.
|
* A lookup map for reading Item content.
|
||||||
|
@ -643,7 +643,7 @@ export const typeListInsertGenericsAfter = (transaction, parent, referenceItem,
|
|||||||
let jsonContent = []
|
let jsonContent = []
|
||||||
const packJsonContent = () => {
|
const packJsonContent = () => {
|
||||||
if (jsonContent.length > 0) {
|
if (jsonContent.length > 0) {
|
||||||
left = new Item(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentAny(jsonContent))
|
left = new Item(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, null, new ContentAny(jsonContent))
|
||||||
left.integrate(transaction, 0)
|
left.integrate(transaction, 0)
|
||||||
jsonContent = []
|
jsonContent = []
|
||||||
}
|
}
|
||||||
@ -665,16 +665,16 @@ export const typeListInsertGenericsAfter = (transaction, parent, referenceItem,
|
|||||||
switch (c.constructor) {
|
switch (c.constructor) {
|
||||||
case Uint8Array:
|
case Uint8Array:
|
||||||
case ArrayBuffer:
|
case ArrayBuffer:
|
||||||
left = new Item(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentBinary(new Uint8Array(/** @type {Uint8Array} */ (c))))
|
left = new Item(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, null, new ContentBinary(new Uint8Array(/** @type {Uint8Array} */ (c))))
|
||||||
left.integrate(transaction, 0)
|
left.integrate(transaction, 0)
|
||||||
break
|
break
|
||||||
case Doc:
|
case Doc:
|
||||||
left = new Item(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentDoc(/** @type {Doc} */ (c)))
|
left = new Item(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, null, new ContentDoc(/** @type {Doc} */ (c)))
|
||||||
left.integrate(transaction, 0)
|
left.integrate(transaction, 0)
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
if (c instanceof AbstractType) {
|
if (c instanceof AbstractType) {
|
||||||
left = new Item(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentType(c))
|
left = new Item(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, null, new ContentType(c))
|
||||||
left.integrate(transaction, 0)
|
left.integrate(transaction, 0)
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Unexpected content type in insert operation')
|
throw new Error('Unexpected content type in insert operation')
|
||||||
@ -862,7 +862,7 @@ export const typeMapSet = (transaction, parent, key, value) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
new Item(createID(ownClientId, getState(doc.store, ownClientId)), left, left && left.lastId, null, null, parent, key, content).integrate(transaction, 0)
|
new Item(createID(ownClientId, getState(doc.store, ownClientId)), left, left && left.lastId, null, null, parent, key, null, content).integrate(transaction, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -166,7 +166,7 @@ const insertNegatedAttributes = (transaction, parent, currPos, negatedAttributes
|
|||||||
negatedAttributes.forEach((val, key) => {
|
negatedAttributes.forEach((val, key) => {
|
||||||
const left = currPos.left
|
const left = currPos.left
|
||||||
const right = currPos.right
|
const right = currPos.right
|
||||||
const nextFormat = new Item(createID(ownClientId, getState(doc.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentFormat(key, val))
|
const nextFormat = new Item(createID(ownClientId, getState(doc.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, null, new ContentFormat(key, val))
|
||||||
nextFormat.integrate(transaction, 0)
|
nextFormat.integrate(transaction, 0)
|
||||||
currPos.right = nextFormat
|
currPos.right = nextFormat
|
||||||
currPos.forward()
|
currPos.forward()
|
||||||
@ -232,7 +232,7 @@ const insertAttributes = (transaction, parent, currPos, attributes) => {
|
|||||||
// save negated attribute (set null if currentVal undefined)
|
// save negated attribute (set null if currentVal undefined)
|
||||||
negatedAttributes.set(key, currentVal)
|
negatedAttributes.set(key, currentVal)
|
||||||
const { left, right } = currPos
|
const { left, right } = currPos
|
||||||
currPos.right = new Item(createID(ownClientId, getState(doc.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentFormat(key, val))
|
currPos.right = new Item(createID(ownClientId, getState(doc.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, null, new ContentFormat(key, val))
|
||||||
currPos.right.integrate(transaction, 0)
|
currPos.right.integrate(transaction, 0)
|
||||||
currPos.forward()
|
currPos.forward()
|
||||||
}
|
}
|
||||||
@ -266,7 +266,7 @@ const insertText = (transaction, parent, currPos, text, attributes) => {
|
|||||||
if (parent._searchMarker) {
|
if (parent._searchMarker) {
|
||||||
updateMarkerChanges(parent._searchMarker, currPos.index, content.getLength())
|
updateMarkerChanges(parent._searchMarker, currPos.index, content.getLength())
|
||||||
}
|
}
|
||||||
right = new Item(createID(ownClientId, getState(doc.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, content)
|
right = new Item(createID(ownClientId, getState(doc.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, null, content)
|
||||||
right.integrate(transaction, 0)
|
right.integrate(transaction, 0)
|
||||||
currPos.right = right
|
currPos.right = right
|
||||||
currPos.index = index
|
currPos.index = index
|
||||||
@ -342,7 +342,7 @@ const formatText = (transaction, parent, currPos, length, attributes) => {
|
|||||||
for (; length > 0; length--) {
|
for (; length > 0; length--) {
|
||||||
newlines += '\n'
|
newlines += '\n'
|
||||||
}
|
}
|
||||||
currPos.right = new Item(createID(ownClientId, getState(doc.store, ownClientId)), currPos.left, currPos.left && currPos.left.lastId, currPos.right, currPos.right && currPos.right.id, parent, null, new ContentString(newlines))
|
currPos.right = new Item(createID(ownClientId, getState(doc.store, ownClientId)), currPos.left, currPos.left && currPos.left.lastId, currPos.right, currPos.right && currPos.right.id, parent, null, null, new ContentString(newlines))
|
||||||
currPos.right.integrate(transaction, 0)
|
currPos.right.integrate(transaction, 0)
|
||||||
currPos.forward()
|
currPos.forward()
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,13 @@ export class UpdateDecoderV1 extends DSDecoderV1 {
|
|||||||
return createID(decoding.readVarUint(this.restDecoder), decoding.readVarUint(this.restDecoder))
|
return createID(decoding.readVarUint(this.restDecoder), decoding.readVarUint(this.restDecoder))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {ID}
|
||||||
|
*/
|
||||||
|
readRedone () {
|
||||||
|
return createID(decoding.readVarUint(this.restDecoder), decoding.readVarUint(this.restDecoder))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read the next client id.
|
* Read the next client id.
|
||||||
* Use this in favor of readID whenever possible to reduce the number of objects created.
|
* Use this in favor of readID whenever possible to reduce the number of objects created.
|
||||||
@ -174,6 +181,7 @@ export class UpdateDecoderV2 extends DSDecoderV2 {
|
|||||||
this.clientDecoder = new decoding.UintOptRleDecoder(decoding.readVarUint8Array(decoder))
|
this.clientDecoder = new decoding.UintOptRleDecoder(decoding.readVarUint8Array(decoder))
|
||||||
this.leftClockDecoder = new decoding.IntDiffOptRleDecoder(decoding.readVarUint8Array(decoder))
|
this.leftClockDecoder = new decoding.IntDiffOptRleDecoder(decoding.readVarUint8Array(decoder))
|
||||||
this.rightClockDecoder = new decoding.IntDiffOptRleDecoder(decoding.readVarUint8Array(decoder))
|
this.rightClockDecoder = new decoding.IntDiffOptRleDecoder(decoding.readVarUint8Array(decoder))
|
||||||
|
this.redoneClockDecoder = new decoding.IntDiffOptRleDecoder(decoding.readVarUint8Array(decoder))
|
||||||
this.infoDecoder = new decoding.RleDecoder(decoding.readVarUint8Array(decoder), decoding.readUint8)
|
this.infoDecoder = new decoding.RleDecoder(decoding.readVarUint8Array(decoder), decoding.readUint8)
|
||||||
this.stringDecoder = new decoding.StringDecoder(decoding.readVarUint8Array(decoder))
|
this.stringDecoder = new decoding.StringDecoder(decoding.readVarUint8Array(decoder))
|
||||||
this.parentInfoDecoder = new decoding.RleDecoder(decoding.readVarUint8Array(decoder), decoding.readUint8)
|
this.parentInfoDecoder = new decoding.RleDecoder(decoding.readVarUint8Array(decoder), decoding.readUint8)
|
||||||
@ -195,6 +203,13 @@ export class UpdateDecoderV2 extends DSDecoderV2 {
|
|||||||
return new ID(this.clientDecoder.read(), this.rightClockDecoder.read())
|
return new ID(this.clientDecoder.read(), this.rightClockDecoder.read())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {ID}
|
||||||
|
*/
|
||||||
|
readRedone () {
|
||||||
|
return new ID(this.clientDecoder.read(), this.redoneClockDecoder.read())
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read the next client id.
|
* Read the next client id.
|
||||||
* Use this in favor of readID whenever possible to reduce the number of objects created.
|
* Use this in favor of readID whenever possible to reduce the number of objects created.
|
||||||
|
@ -50,6 +50,14 @@ export class UpdateEncoderV1 extends DSEncoderV1 {
|
|||||||
encoding.writeVarUint(this.restEncoder, id.clock)
|
encoding.writeVarUint(this.restEncoder, id.clock)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ID} id
|
||||||
|
*/
|
||||||
|
writeRedone (id) {
|
||||||
|
encoding.writeVarUint(this.restEncoder, id.client)
|
||||||
|
encoding.writeVarUint(this.restEncoder, id.clock)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use writeClient and writeClock instead of writeID if possible.
|
* Use writeClient and writeClock instead of writeID if possible.
|
||||||
* @param {number} client
|
* @param {number} client
|
||||||
@ -177,6 +185,7 @@ export class UpdateEncoderV2 extends DSEncoderV2 {
|
|||||||
this.clientEncoder = new encoding.UintOptRleEncoder()
|
this.clientEncoder = new encoding.UintOptRleEncoder()
|
||||||
this.leftClockEncoder = new encoding.IntDiffOptRleEncoder()
|
this.leftClockEncoder = new encoding.IntDiffOptRleEncoder()
|
||||||
this.rightClockEncoder = new encoding.IntDiffOptRleEncoder()
|
this.rightClockEncoder = new encoding.IntDiffOptRleEncoder()
|
||||||
|
this.redoneClockEncoder = new encoding.IntDiffOptRleEncoder()
|
||||||
this.infoEncoder = new encoding.RleEncoder(encoding.writeUint8)
|
this.infoEncoder = new encoding.RleEncoder(encoding.writeUint8)
|
||||||
this.stringEncoder = new encoding.StringEncoder()
|
this.stringEncoder = new encoding.StringEncoder()
|
||||||
this.parentInfoEncoder = new encoding.RleEncoder(encoding.writeUint8)
|
this.parentInfoEncoder = new encoding.RleEncoder(encoding.writeUint8)
|
||||||
@ -191,6 +200,7 @@ export class UpdateEncoderV2 extends DSEncoderV2 {
|
|||||||
encoding.writeVarUint8Array(encoder, this.clientEncoder.toUint8Array())
|
encoding.writeVarUint8Array(encoder, this.clientEncoder.toUint8Array())
|
||||||
encoding.writeVarUint8Array(encoder, this.leftClockEncoder.toUint8Array())
|
encoding.writeVarUint8Array(encoder, this.leftClockEncoder.toUint8Array())
|
||||||
encoding.writeVarUint8Array(encoder, this.rightClockEncoder.toUint8Array())
|
encoding.writeVarUint8Array(encoder, this.rightClockEncoder.toUint8Array())
|
||||||
|
encoding.writeVarUint8Array(encoder, this.redoneClockEncoder.toUint8Array())
|
||||||
encoding.writeVarUint8Array(encoder, encoding.toUint8Array(this.infoEncoder))
|
encoding.writeVarUint8Array(encoder, encoding.toUint8Array(this.infoEncoder))
|
||||||
encoding.writeVarUint8Array(encoder, this.stringEncoder.toUint8Array())
|
encoding.writeVarUint8Array(encoder, this.stringEncoder.toUint8Array())
|
||||||
encoding.writeVarUint8Array(encoder, encoding.toUint8Array(this.parentInfoEncoder))
|
encoding.writeVarUint8Array(encoder, encoding.toUint8Array(this.parentInfoEncoder))
|
||||||
@ -217,6 +227,14 @@ export class UpdateEncoderV2 extends DSEncoderV2 {
|
|||||||
this.rightClockEncoder.write(id.clock)
|
this.rightClockEncoder.write(id.clock)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ID} id
|
||||||
|
*/
|
||||||
|
writeRedone (id) {
|
||||||
|
this.clientEncoder.write(id.client)
|
||||||
|
this.redoneClockEncoder.write(id.clock)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {number} client
|
* @param {number} client
|
||||||
*/
|
*/
|
||||||
|
@ -127,7 +127,7 @@ export const readClientsStructRefs = (decoder, doc) => {
|
|||||||
clientRefs.set(client, { i: 0, refs })
|
clientRefs.set(client, { i: 0, refs })
|
||||||
for (let i = 0; i < numberOfStructs; i++) {
|
for (let i = 0; i < numberOfStructs; i++) {
|
||||||
const info = decoder.readInfo()
|
const info = decoder.readInfo()
|
||||||
switch (binary.BITS5 & info) {
|
switch (binary.BITS4 & info) {
|
||||||
case 0: { // GC
|
case 0: { // GC
|
||||||
const len = decoder.readLen()
|
const len = decoder.readLen()
|
||||||
refs[i] = new GC(createID(client, clock), len)
|
refs[i] = new GC(createID(client, clock), len)
|
||||||
@ -160,6 +160,7 @@ export const readClientsStructRefs = (decoder, doc) => {
|
|||||||
(info & binary.BIT7) === binary.BIT7 ? decoder.readRightID() : null, // right origin
|
(info & binary.BIT7) === binary.BIT7 ? decoder.readRightID() : null, // right origin
|
||||||
cantCopyParentInfo ? (decoder.readParentInfo() ? doc.get(decoder.readString()) : decoder.readLeftID()) : null, // parent
|
cantCopyParentInfo ? (decoder.readParentInfo() ? doc.get(decoder.readString()) : decoder.readLeftID()) : null, // parent
|
||||||
cantCopyParentInfo && (info & binary.BIT6) === binary.BIT6 ? decoder.readString() : null, // parentSub
|
cantCopyParentInfo && (info & binary.BIT6) === binary.BIT6 ? decoder.readString() : null, // parentSub
|
||||||
|
(info & binary.BIT5) === binary.BIT5 ? decoder.readRedone() : null, // redone
|
||||||
readItemContent(decoder, info) // item content
|
readItemContent(decoder, info) // item content
|
||||||
)
|
)
|
||||||
/* A non-optimized implementation of the above algorithm:
|
/* A non-optimized implementation of the above algorithm:
|
||||||
@ -184,6 +185,7 @@ export const readClientsStructRefs = (decoder, doc) => {
|
|||||||
rightOrigin, // right origin
|
rightOrigin, // right origin
|
||||||
cantCopyParentInfo && !hasParentYKey ? decoder.readLeftID() : (parentYKey !== null ? doc.get(parentYKey) : null), // parent
|
cantCopyParentInfo && !hasParentYKey ? decoder.readLeftID() : (parentYKey !== null ? doc.get(parentYKey) : null), // parent
|
||||||
cantCopyParentInfo && (info & binary.BIT6) === binary.BIT6 ? decoder.readString() : null, // parentSub
|
cantCopyParentInfo && (info & binary.BIT6) === binary.BIT6 ? decoder.readString() : null, // parentSub
|
||||||
|
(info & binary.BIT5) === binary.BIT5 ? decoder.readRedone() : null, // redone
|
||||||
readItemContent(decoder, info) // item content
|
readItemContent(decoder, info) // item content
|
||||||
)
|
)
|
||||||
*/
|
*/
|
||||||
|
@ -53,7 +53,7 @@ function * lazyStructReaderGenerator (decoder) {
|
|||||||
const len = decoding.readVarUint(decoder.restDecoder)
|
const len = decoding.readVarUint(decoder.restDecoder)
|
||||||
yield new Skip(createID(client, clock), len)
|
yield new Skip(createID(client, clock), len)
|
||||||
clock += len
|
clock += len
|
||||||
} else if ((binary.BITS5 & info) !== 0) {
|
} else if ((binary.BITS4 & info) !== 0) {
|
||||||
const cantCopyParentInfo = (info & (binary.BIT7 | binary.BIT8)) === 0
|
const cantCopyParentInfo = (info & (binary.BIT7 | binary.BIT8)) === 0
|
||||||
// If parent = null and neither left nor right are defined, then we know that `parent` is child of `y`
|
// If parent = null and neither left nor right are defined, then we know that `parent` is child of `y`
|
||||||
// and we read the next string as parentYKey.
|
// and we read the next string as parentYKey.
|
||||||
@ -68,6 +68,7 @@ function * lazyStructReaderGenerator (decoder) {
|
|||||||
// @ts-ignore Force writing a string here.
|
// @ts-ignore Force writing a string here.
|
||||||
cantCopyParentInfo ? (decoder.readParentInfo() ? decoder.readString() : decoder.readLeftID()) : null, // parent
|
cantCopyParentInfo ? (decoder.readParentInfo() ? decoder.readString() : decoder.readLeftID()) : null, // parent
|
||||||
cantCopyParentInfo && (info & binary.BIT6) === binary.BIT6 ? decoder.readString() : null, // parentSub
|
cantCopyParentInfo && (info & binary.BIT6) === binary.BIT6 ? decoder.readString() : null, // parentSub
|
||||||
|
(info & binary.BIT5) === binary.BIT5 ? decoder.readRedone() : null, // redone
|
||||||
readItemContent(decoder, info) // item content
|
readItemContent(decoder, info) // item content
|
||||||
)
|
)
|
||||||
yield struct
|
yield struct
|
||||||
@ -316,6 +317,7 @@ const sliceStruct = (left, diff) => {
|
|||||||
leftItem.rightOrigin,
|
leftItem.rightOrigin,
|
||||||
leftItem.parent,
|
leftItem.parent,
|
||||||
leftItem.parentSub,
|
leftItem.parentSub,
|
||||||
|
null,
|
||||||
leftItem.content.splice(diff)
|
leftItem.content.splice(diff)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -120,6 +120,6 @@ export const testRelativePositionWithUndo = tc => {
|
|||||||
t.assert(Y.createAbsolutePositionFromRelativePosition(rpos, ydoc, false)?.index === 6)
|
t.assert(Y.createAbsolutePositionFromRelativePosition(rpos, ydoc, false)?.index === 6)
|
||||||
const ydocClone = new Y.Doc()
|
const ydocClone = new Y.Doc()
|
||||||
Y.applyUpdate(ydocClone, Y.encodeStateAsUpdate(ydoc))
|
Y.applyUpdate(ydocClone, Y.encodeStateAsUpdate(ydoc))
|
||||||
t.assert(Y.createAbsolutePositionFromRelativePosition(rpos, ydocClone)?.index === 6)
|
t.assert(Y.createAbsolutePositionFromRelativePosition(rpos, ydocClone)?.index === 1)
|
||||||
t.assert(Y.createAbsolutePositionFromRelativePosition(rpos, ydocClone, false)?.index === 6)
|
t.assert(Y.createAbsolutePositionFromRelativePosition(rpos, ydocClone, false)?.index === 6)
|
||||||
}
|
}
|
||||||
|
@ -2079,7 +2079,7 @@ export const testBestCase = _tc => {
|
|||||||
/**
|
/**
|
||||||
* @type {Y.Item}
|
* @type {Y.Item}
|
||||||
*/
|
*/
|
||||||
const n = new Y.Item(Y.createID(0, 0), null, null, null, null, null, null, c)
|
const n = new Y.Item(Y.createID(0, 0), null, null, null, null, null, null, null, c)
|
||||||
// items.push(n)
|
// items.push(n)
|
||||||
items[i] = n
|
items[i] = n
|
||||||
n.right = prevItem
|
n.right = prevItem
|
||||||
|
Loading…
x
Reference in New Issue
Block a user