refactoring van de cmap structuren bijna compleet
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
"use strict";
|
||||
|
||||
function copy(value) {
|
||||
return value === undefined ? undefined : JSON.parse(JSON.stringify(value));
|
||||
}
|
||||
|
||||
function normalizeConceptName(value) {
|
||||
return String(value || "").trim().toLocaleLowerCase();
|
||||
}
|
||||
|
||||
/** Index lightweight concept placements across stored CMaps. */
|
||||
export class CmapReferenceIndex {
|
||||
constructor() {
|
||||
this.byConceptId = new Map();
|
||||
this.byName = new Map();
|
||||
this.byPage = new Map();
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.byConceptId.clear();
|
||||
this.byName.clear();
|
||||
this.byPage.clear();
|
||||
}
|
||||
|
||||
load(placements = [], conceptMaps = [], canonicalPageReference = (value) => value,
|
||||
normalizeName = normalizeConceptName) {
|
||||
this.clear();
|
||||
const mapTitles = new Map(conceptMaps
|
||||
.filter((map) => map && map.slug)
|
||||
.map((map) => [map.slug, map.title || map.slug]));
|
||||
const pageByConcept = new Map();
|
||||
for (const placement of placements) {
|
||||
if (!placement?.conceptId || !placement.pageSlug) continue;
|
||||
pageByConcept.set(placement.conceptId,
|
||||
canonicalPageReference(placement.pageSlug).toLocaleLowerCase());
|
||||
}
|
||||
for (const placement of placements) {
|
||||
if (!placement?.conceptId || !placement.cmapSlug) continue;
|
||||
const conceptId = String(placement.conceptId);
|
||||
const slug = String(placement.cmapSlug);
|
||||
const nameKey = normalizeName(placement.label);
|
||||
if (nameKey) this.byName.set(nameKey, conceptId);
|
||||
if (!this.byConceptId.has(conceptId)) this.byConceptId.set(conceptId, new Map());
|
||||
const maps = this.byConceptId.get(conceptId);
|
||||
const existing = maps.get(slug);
|
||||
maps.set(slug, {
|
||||
slug,
|
||||
title: mapTitles.get(slug) || placement.cmapTitle || slug,
|
||||
count: (existing?.count || 0) + (Number(placement.count) || 0)
|
||||
});
|
||||
|
||||
const pageKey = pageByConcept.get(conceptId);
|
||||
if (!pageKey) continue;
|
||||
if (!this.byPage.has(pageKey)) this.byPage.set(pageKey, new Map());
|
||||
const pageConcepts = this.byPage.get(pageKey);
|
||||
if (!pageConcepts.has(conceptId)) {
|
||||
pageConcepts.set(conceptId, {
|
||||
conceptId,
|
||||
label: placement.label || "Concept",
|
||||
count: 0,
|
||||
maps: new Map()
|
||||
});
|
||||
}
|
||||
const concept = pageConcepts.get(conceptId);
|
||||
const count = Number(placement.count) || 0;
|
||||
concept.count += count;
|
||||
const pageMap = concept.maps.get(slug);
|
||||
concept.maps.set(slug, {
|
||||
slug,
|
||||
title: mapTitles.get(slug) || placement.cmapTitle || slug,
|
||||
count: count + (pageMap?.count || 0)
|
||||
});
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
mapsFor(conceptId) {
|
||||
return Array.from(this.byConceptId.get(String(conceptId))?.values() || [])
|
||||
.map(copy);
|
||||
}
|
||||
|
||||
countFor(conceptId) {
|
||||
return this.mapsFor(conceptId).reduce((sum, map) => sum + map.count, 0);
|
||||
}
|
||||
|
||||
conceptIdForName(label) {
|
||||
return this.byName.get(normalizeConceptName(label)) || null;
|
||||
}
|
||||
|
||||
pageConcepts(pageReference) {
|
||||
return Array.from(this.byPage.get(String(pageReference).toLocaleLowerCase())?.values() || [])
|
||||
.map((concept) => ({ ...copy(concept), maps: new Map(concept.maps) }));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user