You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

75 lines
2.4 KiB

import type { PredicateNode, SubjectNode } from "@ldo/rdf-utils";
import { literal, quad } from "@ldo/rdf-utils";
import type { ProxyContext } from "../ProxyContext";
import {
languageKeyToLiteralLanguage,
quadsToLanguageQuadMap,
languageDeleteMatch,
} from "./languageUtils";
import type { LanguageMap, LanguageSetMap } from "./languagesOf";
import LanguageSet from "./languageSet";
export function createLanguageMapProxy<
Target extends LanguageMap | LanguageSetMap,
>(
subject: SubjectNode,
predicate: PredicateNode,
proxyContext: ProxyContext,
isArray: boolean,
): Target {
const target: Target = {} as Target;
// Function to call to update the target to represent what's in the dataset
const targetSetter = (target: Target) => {
// Clear the target
Object.keys(target).forEach((key) => delete target[key]);
// Add current language map to target
const allQuads = proxyContext.dataset.match(subject, predicate);
const languageQuadMap = quadsToLanguageQuadMap(allQuads);
Object.entries(languageQuadMap).forEach(([language, quads]) => {
const stringArray = quads.toArray().map((quad) => quad.object.value);
if (isArray) {
target[language] = new Set(stringArray);
} else {
target[language] = stringArray[0];
}
});
};
targetSetter(target);
return new Proxy<Target>(target, {
get: (target, key) => {
targetSetter(target);
if (typeof key !== "string") {
return Reflect.get(target, key);
}
if (isArray) {
return new LanguageSet(subject, predicate, key, proxyContext);
}
return Reflect.get(target, key);
},
set: (target, key, value) => {
const language = languageKeyToLiteralLanguage(key);
// Delete all quads with the language currently
if (!isArray) {
languageDeleteMatch(proxyContext.dataset, subject, predicate, language);
}
// Add the new quad for the language
proxyContext.writeGraphs.forEach((writeGraph) => {
proxyContext.dataset.add(
quad(subject, predicate, literal(value, language), writeGraph),
);
});
return Reflect.set(target, key, value);
},
deleteProperty: (target, key) => {
languageDeleteMatch(
proxyContext.dataset,
subject,
predicate,
languageKeyToLiteralLanguage(key),
);
return Reflect.deleteProperty(target, key);
},
}) as Target;
}