UNPKG

incubed

Version:

Typescript-version of the incubed client

105 lines 3.75 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); class DeltaHistory { constructor(init = [], deltaStrings = false) { if (deltaStrings) this.loadDeltaStrings(init); else { this.data = []; if (init) this.addState(0, init); } } getData(index) { const res = []; for (const d of this.data) { if (d.block > index) return res; res.splice(d.start, d.len, ...d.data); } return res; } getLastIndex() { return this.data.length && this.data[this.data.length - 1].block; } addState(start, data) { const prev = this.getData(start - 1); const delta = createDelta(prev, data, start); if (!delta) return; if (!this.data.length || this.data[this.data.length - 1].block < start) this.data.push(delta); else { for (let i = this.data.length - 1; i >= 0; i--) { const d = this.data[i]; if (d.block === start) { const next = [...prev]; next.splice(d.start, d.len, ...d.data); // old state if (i + 1 < this.data.length) next.splice(this.data[i + 1].start, this.data[i + 1].len, ...this.data[i + 1].data); // next state this.data[i] = delta; if (i + 1 == this.data.length) return; const nextDelta = createDelta(data, next, this.data[i + 1].block); if (!nextDelta) this.data.splice(i + 1, 1); else this.data[i + 1] = nextDelta; return; } if (d.block < start) { const n = this.data[i + 1]; const next = [...prev]; next.splice(n.start, n.len, ...n.data); // next state const nextDelta = createDelta(data, next, n.block); if (!nextDelta) n.block = start; else this.data.splice(i + 1, 1, delta, nextDelta); return; } } // we need to insert into first pos const dn = createDelta(data, this.data[0].data, this.data[0].block); if (!dn) this.data[0].block = start; else this.data.splice(0, 1, delta, dn); } } toDeltaStrings() { return this.data.map(_ => `${_.block.toString(16)}:${_.start.toString(16)}:${_.len.toString(16)}:${_.data.join(':')}`); } loadDeltaStrings(deltas) { this.data = deltas.map(_ => { const d = _.split(':'); const [block, start, len] = d.slice(0, 3).map(_ => parseInt(_, 16)); return { block, start, len, data: d.slice(3) }; }); } } exports.default = DeltaHistory; function createDelta(a, b, block) { const first = firstChange(a, b, 1); const last = firstChange(a, b, -1); // no change if (a.length === b.length && first === a.length) return null; return { block, start: first, len: a.length - last - first, data: b.slice(first, b.length - last) }; } function firstChange(a, b, dir = 1) { const len = Math.min(a.length, b.length); for (let i = 0; i < len; i++) { if (dir === 1 && a[i] != b[i]) return i; if (dir === -1 && a[a.length - 1 - i] != b[b.length - 1 - i]) return i; } return len; } //# sourceMappingURL=DeltaHistory.js.map