UNPKG

soocrate-core

Version:

this is the core of soocrate application

118 lines (108 loc) 3.69 kB
import { TextEvent } from './TextEvent' var debug = require('debug')('CRATE:Communication:TextManager:InsertManager') export class InsertManager extends TextEvent { constructor(opts) { const EventName = opts.EventName || 'Insert' super({ EventName, ...opts }) this._textManager = opts.TextManager this.action = this.insert this._lastSentId = null } /*! * \brief local insertion of a character inside the sequence structure. It * broadcasts the operation to the rest of the network. * \param character the character to insert in the sequence * \param index the index in the sequence to insert * \return the identifier freshly allocated */ insert({ packet, position, source = 'user' }) { if (this.isItConvertibleToJSON(packet)) { var pair = this.insertLSEQ(packet, position) this._document.delta.ops.splice(position, 0, { insert: packet.content, attributes: packet.attributes }) debug('local Insert', { packet, position, source }) if (source === 'user') { { this.broadcast({ id: this._document.uid, pair }) this.setLastChangesTime() } } } } /** * Insert a value at the targeted index. * @param {Object} element The element to insert, e.g. a character if the * sequence is a string. * @param {Number} index The position in the array. * @return {Object} {_e: element of Object type, _i: Identifier} */ insertLSEQ(element, index) { const pei = this._sequence._get(index), // #1a previous bound qei = this._sequence._get(index + 1) // #1b next bound // #2a incrementing the local counter this._sequence._c += 1 // #2b generating the id inbetween the bounds const id = this._sequence.alloc(pei, qei) // #3 add it to the structure and return value const pair = { elem: { id, ...element }, id: id } this._sequence.applyInsert(pair) return pair } getIDBeforeInsert(sequence) { const pei = sequence._get(index), // #1a previous bound qei = sequence._get(index + 1) // #1b next bound // #2a incrementing the local counter this._c += 1 // #2b generating the id inbetween the bounds const id = sequence.alloc(pei, qei) return id } /*! * \brief insertion of an element from a remote site. It emits 'remoteInsert' * with the index of the element to insert, -1 if already existing. * \param ei the result of the remote insert operation * \param origin the origin id of the insert operation */ receive({ id, pair, antientropy = false }) { const index = this._sequence.applyInsert(pair, false) debug('remoteInsert', 'pair', pair, ' sequence Index ', index) this._document.delta.ops.splice(index - 1, 0, { insert: pair.elem.content, attributes: pair.elem.attributes }) if (index >= 0) { // this.emit('remoteInsert', pair.elem, index); this.setLastChangesTime() if (!antientropy) { const range = { index: index, length: 0 } const msg = { range, id, stream: false } this.Event('Caret', msg) } } } /** * Validate that the message is convertable to JSON * @param {*} msg */ isItConvertibleToJSON(msg) { try { const test = JSON.parse(JSON.stringify(msg)) return true } catch (e) { console.error('The object cannot be convert to json ', e, insertMsg) return false } } }