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