assets/src/services/crdt_linear.js
/**
 * Remove given local change item from current linear crdt.
 *
 * @typedef {List<List<import('./char').Char>>} MultiCharList
 * @typedef {Array<import('./char').Char>} RemovedChar
 * @param {MultiCharList} crdt
 * @param {LocalChange.LocalChange} change
 * @return {[MultiCharList, RemovedChar]}
 */
Remove given local change item from current linear crdt.
Remove given local change item from current linear crdt .
function updateCrdtRemove (crdt, change) {
  const lines = crdt.slice(change.from.line, change.to.line + 1)
  const linesAndUpdates = lines.map((line, index) => {
    let startIndex
    let endIndex
    if (index === 0) {
      startIndex = change.from.ch
    } else {
      startIndex = 0
    }
    if (index === lines.size - 1) {
      endIndex = change.to.ch
    } else {
      endIndex = line.size
    }
    const toRemove = line.slice(startIndex, endIndex)
    if (toRemove.size !== endIndex - startIndex) {
      throw new Error('size does not match')
    }
    const updatedLine = line.splice(startIndex, endIndex - startIndex).toList()
    return [updatedLine, toRemove]
  })
  const updatedLines = linesAndUpdates.map(tuple => tuple[0])
  const toRemove = linesAndUpdates.flatMap(tuple => tuple[1])
  let newCrdt
  if (lines.size === 1) {
    newCrdt = crdt.set(change.from.line, updatedLines.first())
  } else {
    const remainingLine = updatedLines
      .first()
      .concat(updatedLines.last())
      .toList()
    newCrdt = crdt.splice(change.from.line, lines.size, remainingLine).toList()
  }
  return [newCrdt, toRemove.toArray()]
}
function updateCrdtRemove ( crdt , change ) { const lines = crdt . slice ( change . from . line , change . to . line + 1 ) const linesAndUpdates = lines . map ( ( line , index ) => { let startIndex let endIndex if ( index === 0 ) { startIndex = change . from . ch } else { startIndex = 0 } if ( index === lines . size - 1 ) { endIndex = change . to . ch } else { endIndex = line . size } const toRemove = line . slice ( startIndex , endIndex ) if ( toRemove . size !== endIndex - startIndex ) { throw new Error ( 'size does not match' ) } const updatedLine = line . splice ( startIndex , endIndex - startIndex ) . toList ( ) return [ updatedLine , toRemove ] } ) const updatedLines = linesAndUpdates . map ( tuple => tuple [ 0 ] ) const toRemove = linesAndUpdates . flatMap ( tuple => tuple [ 1 ] ) let newCrdt if ( lines . size === 1 ) { newCrdt = crdt . set ( change . from . line , updatedLines . first ( ) ) } else { const remainingLine = updatedLines . first ( ) . concat ( updatedLines . last ( ) ) . toList ( ) newCrdt = crdt . splice ( change . from . line , lines . size , remainingLine ) . toList ( ) } return [ newCrdt , toRemove . toArray ( ) ] }
Remove given local change item from current linear crdt.
Remove given local change item from current linear crdt .
// First line // Last line // Only the first and last line should be non-empty, so we just keep those.