json-joy
Version:
Collection of libraries for building collaborative editing apps.
118 lines (117 loc) • 2.92 kB
JavaScript
import { tick } from '../../../json-crdt-patch/clock';
import { AbstractRga } from '../rga/AbstractRga';
/**
* @ignore
* @category CRDT Node
*/
export class BinChunk {
id;
span;
del;
data;
len;
p;
l;
r;
p2;
l2;
r2;
s;
constructor(id, span, buf) {
this.id = id;
this.span = span;
this.len = buf ? span : 0;
this.del = !buf;
this.p = undefined;
this.l = undefined;
this.r = undefined;
this.s = undefined;
this.data = buf;
}
merge(data) {
const length = this.data.length;
const combined = new Uint8Array(length + data.length);
combined.set(this.data);
combined.set(data, length);
this.data = combined;
this.span = combined.length;
}
split(ticks) {
if (!this.del) {
const data = this.data;
const rightBuffer = data.subarray(ticks);
const chunk = new BinChunk(tick(this.id, ticks), this.span - ticks, rightBuffer);
this.data = data.subarray(0, ticks);
this.span = ticks;
return chunk;
}
const chunk = new BinChunk(tick(this.id, ticks), this.span - ticks, undefined);
this.span = ticks;
return chunk;
}
delete() {
this.del = true;
this.data = undefined;
}
clone() {
const chunk = new BinChunk(this.id, this.span, this.data);
return chunk;
}
view() {
return this.data || new Uint8Array(0);
}
}
/**
* Represents the `bin` type in JSON CRDT. The `bin` is a blob of binary data,
* powered by a Replicated Growable Array (RGA) algorithm.
*
* @category CRDT Node
*/
export class BinNode extends AbstractRga {
// ----------------------------------------------------------------- JsonNode
/** @ignore */
_view = null;
view() {
if (this._view)
return this._view;
const res = new Uint8Array(this.length());
let offset = 0;
let chunk = this.first();
while (chunk) {
if (!chunk.del) {
const buf = chunk.data;
res.set(buf, offset);
offset += buf.length;
}
chunk = this.next(chunk);
}
return (this._view = res);
}
/** @ignore */
children() { }
/** @ignore */
child() {
return undefined;
}
/** @ignore */
container() {
return undefined;
}
/** @ignore */
api = undefined;
name() {
return 'bin';
}
// -------------------------------------------------------------- AbstractRga
/** @ignore */
createChunk(id, buf) {
return new BinChunk(id, buf ? buf.length : 0, buf);
}
/** @ignore */
onChange() {
this._view = null;
}
toStringName() {
return this.name();
}
}