async function getNode(id, tree={}, generation=15, label='', args={}) {
if (generation <= 0) return null;
if (!tree[id]) {
tree[id] = {
type: /^[0-9]/.test(id) ? 'def' : 'thm',
label: label,
children: [],
inProcess: false,
failed: false,
};
}
if (!nodeType(id)) return null;
tree[id].inProcess = true;
try {
const response = await fetch(url + `${id}/${id}.json`);
if (response.ok) {
const data = await response.json();
tree[id].data = data;
if (tree[id].label === "") tree[id].label = data.name;
tree[id].inProcess = false;
tree[id].failed = false;
let dependents = data.dependencies || {};
if (data.type && typeof data.type === 'object') {
dependents = { ...dependents, ...data.type };
}
const sections = ['statements', 'proofs', 'definitions'];
sections.forEach(section => {
Object.values(data[section] || {}).forEach(item => {
if (item.dependencies) {
dependents = { ...dependents, ...item.dependencies };
}
});
});
for (let key in dependents) {
let depId = key;
let label = dependents[key];
if (!nodeType(key) && label[8] == ':') {
[depId, label] = label.split(':');
}
if (tree.hasOwnProperty(depId)) {
tree[depId].children.push(id);
if (label != tree[depId].label) {
tree[depId].label = tree[depId].data.name;
}
} else {
if (!nodeType(depId)) depId += ':' + label;
tree[depId] = {
type: /^[0-9]/.test(depId) ? 'def' : 'thm',
label: label,
children: [id],
inProcess: false,
failed: !nodeType(depId)
};
await getNode(depId, tree, generation-1, label);
}
}
} else {
tree[id].failed = true;
}
} catch (error) {
tree[id].failed = true;
} finally {
tree[id].inProcess = false;
}
return tree;
}