json-joy
Version:
Collection of libraries for building collaborative editing apps.
102 lines • 3.45 kB
JavaScript
import { Patch, InsValOp, InsObjOp, InsVecOp, InsStrOp, InsBinOp, InsArrOp, UpdArrOp, DelOp, } from '../../../json-crdt-patch';
/** Operation targets specific node: the operation has `.obj` property. */
const operationTargetsNode = (op) => {
return (op instanceof InsValOp ||
op instanceof InsObjOp ||
op instanceof InsVecOp ||
op instanceof InsStrOp ||
op instanceof InsBinOp ||
op instanceof InsArrOp ||
op instanceof UpdArrOp ||
op instanceof DelOp);
};
export class ChangeEvent {
raw;
api;
constructor(raw, api) {
this.raw = raw;
this.api = api;
}
origin() {
const { raw, api } = this;
return raw instanceof Set
? 2 /* ChangeEventOrigin.Reset */
: typeof raw === 'number'
? 0 /* ChangeEventOrigin.Local */
: raw instanceof Patch
? raw.getId()?.sid === api.model.clock.sid
? 0 /* ChangeEventOrigin.Local */
: 1 /* ChangeEventOrigin.Remote */
: 0 /* ChangeEventOrigin.Local */;
}
isLocal() {
return this.origin() === 0 /* ChangeEventOrigin.Local */;
}
isReset() {
return this.raw instanceof Set;
}
_direct = null;
/**
* JSON CRDT nodes directly affected by this change event, i.e. nodes
* which are direct targets of operations in the change.
*/
direct() {
let direct = this._direct;
DIRECT: if (!direct) {
const raw = this.raw;
if (raw instanceof Set) {
this._direct = direct = raw;
break DIRECT;
}
this._direct = direct = new Set();
const index = this.api.model.index;
if (typeof raw === 'number') {
const startIndex = raw;
const api = this.api;
const ops = api.builder.patch.ops;
for (let i = startIndex; i < ops.length; i++) {
const op = ops[i];
if (operationTargetsNode(op)) {
const node = index.get(op.obj);
if (node)
direct.add(node);
}
}
}
else if (raw instanceof Patch) {
const ops = raw.ops;
const length = ops.length;
for (let i = 0; i < length; i++) {
const op = ops[i];
if (operationTargetsNode(op)) {
const node = index.get(op.obj);
if (node)
direct.add(node);
}
}
}
}
return direct;
}
_parents = null;
/**
* JSON CRDT nodes which are parents of directly affected nodes in this
* change event.
*/
parents() {
let parents = this._parents;
if (!parents) {
this._parents = parents = new Set();
const direct = this.direct();
for (const start of direct) {
let parent = start.parent;
while (parent && !parents.has(parent)) {
parents.add(parent);
parent = parent.parent;
}
}
}
return parents;
}
}
//# sourceMappingURL=events.js.map