json-joy
Version:
Collection of libraries for building collaborative editing apps.
166 lines • 5.79 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Decoder = void 0;
const tslib_1 = require("tslib");
const nodes = tslib_1.__importStar(require("../../../nodes"));
const ClockDecoder_1 = require("../../../../json-crdt-patch/codec/clock/ClockDecoder");
const clock_1 = require("../../../../json-crdt-patch/clock");
const Model_1 = require("../../../model/Model");
class Decoder {
decode(doc) {
const [time, root] = doc;
const isServerTime = typeof time === 'number';
if (isServerTime) {
this.time = time;
}
else {
this.clockDecoder = ClockDecoder_1.ClockDecoder.fromArr(time);
}
const model = isServerTime
? Model_1.Model.withServerClock(void 0, time)
: Model_1.Model.create(void 0, this.clockDecoder.clock);
const val = root ? this.decNode(model, root) : Model_1.UNDEFINED;
model.root = new nodes.RootNode(model, val.id);
return model;
}
ts(x) {
if (typeof x === 'number') {
return new clock_1.Timestamp(1 /* SESSION.SERVER */, this.time - x);
}
else {
const [sid, time] = x;
if (sid < 0) {
return this.clockDecoder.decodeId(-sid, time);
}
else {
return new clock_1.Timestamp(sid, time);
}
}
}
decNode(model, node) {
switch (node[0]) {
case 0 /* JsonCrdtDataType.con */:
return this.decCon(model, node);
case 1 /* JsonCrdtDataType.val */:
return this.decVal(model, node);
case 2 /* JsonCrdtDataType.obj */:
return this.decObj(model, node);
case 3 /* JsonCrdtDataType.vec */:
return this.decVec(model, node);
case 4 /* JsonCrdtDataType.str */:
return this.decStr(model, node);
case 5 /* JsonCrdtDataType.bin */:
return this.decBin(model, node);
case 6 /* JsonCrdtDataType.arr */:
return this.decArr(model, node);
}
throw new Error('UNKNOWN_NODE');
}
decCon(doc, node) {
const id = this.ts(node[1]);
let data = node[2];
if (node.length > 3) {
const specialData = node[3];
if (!specialData)
data = undefined;
else
data = this.ts(specialData);
}
const obj = new nodes.ConNode(id, data);
doc.index.set(id, obj);
return obj;
}
decVal(doc, node) {
const id = this.ts(node[1]);
const child = this.decNode(doc, node[2]);
const obj = new nodes.ValNode(doc, id, child.id);
doc.index.set(id, obj);
return obj;
}
decObj(model, node) {
const id = this.ts(node[1]);
const obj = new nodes.ObjNode(model, id);
const map = node[2];
const keys = Object.keys(map);
const length = keys.length;
for (let i = 0; i < length; i++) {
const key = keys[i];
const val = this.decNode(model, map[key]);
obj.put(key, val.id);
}
model.index.set(id, obj);
return obj;
}
decVec(model, node) {
const id = this.ts(node[1]);
const obj = new nodes.VecNode(model, id);
const map = node[2];
const elements = obj.elements;
const length = map.length;
for (let i = 0; i < length; i++) {
const item = map[i];
if (!item)
elements.push(undefined);
else {
const child = this.decNode(model, item);
elements.push(child.id);
}
}
model.index.set(id, obj);
return obj;
}
decStr(doc, node) {
const id = this.ts(node[1]);
const obj = new nodes.StrNode(id);
const chunks = node[2];
const size = chunks.length;
let i = 0;
obj.ingest(size, () => {
const chunk = chunks[i++];
const chunkId = this.ts(chunk[0]);
const content = chunk[1];
if (typeof content === 'number')
return new nodes.StrChunk(chunkId, content, '');
return new nodes.StrChunk(chunkId, content.length, content);
});
doc.index.set(id, obj);
return obj;
}
decBin(doc, node) {
const id = this.ts(node[1]);
const obj = new nodes.BinNode(id);
const chunks = node[2];
const size = chunks.length;
let i = 0;
obj.ingest(size, () => {
const chunk = chunks[i++];
const chunkId = this.ts(chunk[0]);
const content = chunk[1];
if (typeof content === 'number')
return new nodes.BinChunk(chunkId, content, undefined);
return new nodes.BinChunk(chunkId, content.length, content);
});
doc.index.set(id, obj);
return obj;
}
decArr(doc, node) {
const id = this.ts(node[1]);
const obj = new nodes.ArrNode(doc, id);
const chunks = node[2];
const size = chunks.length;
let i = 0;
obj.ingest(size, () => {
const chunk = chunks[i++];
const chunkId = this.ts(chunk[0]);
const content = chunk[1];
if (typeof content === 'number')
return new nodes.ArrChunk(chunkId, content, undefined);
const ids = content.map((c) => this.decNode(doc, c).id);
return new nodes.ArrChunk(chunkId, content.length, ids);
});
doc.index.set(id, obj);
return obj;
}
}
exports.Decoder = Decoder;
//# sourceMappingURL=Decoder.js.map