in packages/database/src/core/snap/nodeFromJSON.ts [40:132]
export function nodeFromJSON(
json: unknown | null,
priority: unknown = null
): Node {
if (json === null) {
return ChildrenNode.EMPTY_NODE;
}
if (typeof json === 'object' && '.priority' in json) {
priority = json['.priority'];
}
assert(
priority === null ||
typeof priority === 'string' ||
typeof priority === 'number' ||
(typeof priority === 'object' && '.sv' in (priority as object)),
'Invalid priority type found: ' + typeof priority
);
if (typeof json === 'object' && '.value' in json && json['.value'] !== null) {
json = json['.value'];
}
// Valid leaf nodes include non-objects or server-value wrapper objects
if (typeof json !== 'object' || '.sv' in json) {
const jsonLeaf = json as string | number | boolean | Indexable;
return new LeafNode(jsonLeaf, nodeFromJSON(priority));
}
if (!(json instanceof Array) && USE_HINZE) {
const children: NamedNode[] = [];
let childrenHavePriority = false;
const hinzeJsonObj = json;
each(hinzeJsonObj, (key, child) => {
if (key.substring(0, 1) !== '.') {
// Ignore metadata nodes
const childNode = nodeFromJSON(child);
if (!childNode.isEmpty()) {
childrenHavePriority =
childrenHavePriority || !childNode.getPriority().isEmpty();
children.push(new NamedNode(key, childNode));
}
}
});
if (children.length === 0) {
return ChildrenNode.EMPTY_NODE;
}
const childSet = buildChildSet(
children,
NAME_ONLY_COMPARATOR,
namedNode => namedNode.name,
NAME_COMPARATOR
) as SortedMap<string, Node>;
if (childrenHavePriority) {
const sortedChildSet = buildChildSet(
children,
PRIORITY_INDEX.getCompare()
);
return new ChildrenNode(
childSet,
nodeFromJSON(priority),
new IndexMap(
{ '.priority': sortedChildSet },
{ '.priority': PRIORITY_INDEX }
)
);
} else {
return new ChildrenNode(
childSet,
nodeFromJSON(priority),
IndexMap.Default
);
}
} else {
let node: Node = ChildrenNode.EMPTY_NODE;
each(json, (key: string, childData: unknown) => {
if (contains(json as object, key)) {
if (key.substring(0, 1) !== '.') {
// ignore metadata nodes.
const childNode = nodeFromJSON(childData);
if (childNode.isLeafNode() || !childNode.isEmpty()) {
node = node.updateImmediateChild(key, childNode);
}
}
}
});
return node.updatePriority(nodeFromJSON(priority));
}
}