med-notes/resource-provider/helper.js

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);
}