json-joy
Version:
Collection of libraries for building collaborative editing apps.
57 lines (56 loc) • 1.84 kB
JavaScript
import { CONST, updateNum } from '../json-hash/hash';
import { ConNode, ValNode, ObjNode, VecNode, ArrNode } from './nodes';
import { AbstractRga } from './nodes/rga';
import { last2 } from 'sonic-forest/lib/util2';
export const updateId = (state, id) => {
const time = id.time;
state = updateNum(state, state ^ time);
state = updateNum(state, id.sid ^ time);
return state;
};
export const updateRga = (state, node) => {
state = updateNum(state, node.length());
state = updateNum(state, node.size());
const maxIdChunk = last2(node.ids);
if (maxIdChunk)
state = updateId(state, maxIdChunk.id);
return updateId(state, node.id);
};
/**
* Updates the hash state with the given JSON CRDT node.
* @param state Current hash state.
* @param node JSON CRDT node from which to compute the hash.
*/
export const updateNode = (state, node) => {
if (node instanceof ConNode)
return updateId(state, node.id);
if (node instanceof ValNode) {
const child = node.child();
if (child)
state = updateNode(state, child);
return updateId(state, node.id);
}
if (node instanceof ObjNode || node instanceof VecNode) {
node.children((child) => {
state = updateNode(state, child);
});
return updateId(state, node.id);
}
if (node instanceof ArrNode) {
node.children((child) => {
state = updateNode(state, child);
});
}
if (node instanceof AbstractRga)
return updateRga(state, node);
throw new Error('UNKNOWN_NODE');
};
export const hashId = (id) => {
return updateId(CONST.START_STATE, id);
};
export const hashNode = (node) => {
return updateNode(CONST.START_STATE, node) >>> 0;
};
export const hashModel = (model) => {
return hashNode(model.root);
};