69 lines
1.8 KiB
JavaScript
69 lines
1.8 KiB
JavaScript
import { promises as fs } from "fs";
|
|
import path from "path";
|
|
import { FILENAME_REGEX, STATIC_DIR, TOPICS } from "./constants.js";
|
|
|
|
export const cache = new Map();
|
|
|
|
function getObjectWithMaxTimestamp(array) {
|
|
if (!array || array.length === 0) {
|
|
return null;
|
|
}
|
|
|
|
return array.reduce((max, current) => {
|
|
return current.timestamp > max.timestamp ? current : max;
|
|
});
|
|
}
|
|
|
|
async function populateResources() {
|
|
const filenamesRaw = await fs.readdir(STATIC_DIR);
|
|
const filenames = filenamesRaw
|
|
.filter((filename) => FILENAME_REGEX.test(filename))
|
|
.map((filename) => {
|
|
const parts = filename.replace(".md", "").split("_");
|
|
if (parts.length !== 4 || parts[0] !== "F") {
|
|
console.warn(`File not following format: ${filename}`);
|
|
return;
|
|
}
|
|
|
|
const topicSeq = Number(parts[1].substring(1));
|
|
const resourceSeq = Number(parts[2].substring(1));
|
|
const timestamp = Number(parts[3]);
|
|
return { topicSeq, resourceSeq, timestamp, filename };
|
|
});
|
|
|
|
const topicsBySeq = Object.groupBy(filenames, ({ topicSeq }) => topicSeq);
|
|
|
|
TOPICS.forEach((topic) => {
|
|
if (topic.seq in topicsBySeq) {
|
|
const resourcesBySeq = Object.groupBy(
|
|
topicsBySeq[topic.seq],
|
|
({ resourceSeq }) => resourceSeq,
|
|
);
|
|
|
|
topic.resources.forEach((resource) => {
|
|
if (resource.seq in resourcesBySeq) {
|
|
const latestResource = getObjectWithMaxTimestamp(
|
|
resourcesBySeq[resource.seq],
|
|
);
|
|
resource.filename = latestResource.filename;
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
export async function getStructure({ refresh = false } = {}) {
|
|
const structureKey = "structure";
|
|
|
|
if (refresh) {
|
|
cache.delete(structureKey);
|
|
}
|
|
|
|
if (!cache.has(structureKey)) {
|
|
await populateResources();
|
|
cache.set(structureKey, TOPICS);
|
|
}
|
|
|
|
return cache.get(structureKey);
|
|
}
|