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.
115 lines
3.5 KiB
115 lines
3.5 KiB
import { blankNode, namedNode, quad } from "@rdfjs/data-model";
|
|
import type { BlankNode, NamedNode } from "@rdfjs/types";
|
|
import { addObjectToDataset } from "../util/addObjectToDataset";
|
|
import { deleteValueFromDataset } from "./deleteFromDataset";
|
|
import {
|
|
_getUnderlyingDataset,
|
|
_getUnderlyingNode,
|
|
_proxyContext,
|
|
_writeGraphs,
|
|
} from "../types";
|
|
import { getValueForKey } from "./getValueForKey";
|
|
import type { ProxyContext } from "../ProxyContext";
|
|
|
|
export interface SubjectProxyTarget {
|
|
"@id": NamedNode | BlankNode;
|
|
}
|
|
|
|
export function createSubjectHandler(
|
|
initialProxyContext: ProxyContext,
|
|
): ProxyHandler<SubjectProxyTarget> {
|
|
let proxyContext = initialProxyContext;
|
|
return {
|
|
get(target: SubjectProxyTarget, key: string | symbol) {
|
|
switch (key) {
|
|
case _getUnderlyingDataset:
|
|
return proxyContext.dataset;
|
|
case _getUnderlyingNode:
|
|
return target["@id"];
|
|
case _proxyContext:
|
|
return proxyContext;
|
|
case _writeGraphs:
|
|
return proxyContext.writeGraphs;
|
|
case "@context":
|
|
return proxyContext.contextUtil.context;
|
|
}
|
|
return getValueForKey(target, key, proxyContext);
|
|
},
|
|
getOwnPropertyDescriptor(target: SubjectProxyTarget, key: string) {
|
|
return {
|
|
value: getValueForKey(target, key, proxyContext),
|
|
writable: true,
|
|
enumerable: true,
|
|
configurable: true,
|
|
};
|
|
},
|
|
ownKeys(target) {
|
|
const subject = target["@id"];
|
|
const tripleDataset = proxyContext.dataset.match(subject);
|
|
const keys: Set<string> = new Set(["@id"]);
|
|
tripleDataset.toArray().forEach((quad) => {
|
|
keys.add(
|
|
proxyContext.contextUtil.iriToKey(
|
|
quad.predicate.value,
|
|
proxyContext.getRdfType(subject),
|
|
),
|
|
);
|
|
});
|
|
return Array.from(keys);
|
|
},
|
|
set: (target: SubjectProxyTarget, key, value) => {
|
|
if (key === _proxyContext) {
|
|
proxyContext = value;
|
|
return true;
|
|
}
|
|
if (
|
|
key === "@id" &&
|
|
(typeof value === "string" || typeof value == "undefined")
|
|
) {
|
|
const newSubjectNode = value ? namedNode(value) : blankNode();
|
|
// Replace Subject Quads
|
|
const currentSubjectQuads = proxyContext.dataset
|
|
.match(target["@id"])
|
|
.toArray();
|
|
const newSubjectQuads = currentSubjectQuads.map((curQuad) =>
|
|
quad(
|
|
newSubjectNode,
|
|
curQuad.predicate,
|
|
curQuad.object,
|
|
curQuad.graph,
|
|
),
|
|
);
|
|
currentSubjectQuads.forEach((curQuad) =>
|
|
proxyContext.dataset.delete(curQuad),
|
|
);
|
|
proxyContext.dataset.addAll(newSubjectQuads);
|
|
// Replace Object Quads
|
|
const currentObjectQuads = proxyContext.dataset
|
|
.match(undefined, undefined, target["@id"])
|
|
.toArray();
|
|
const newObjectQuads = currentObjectQuads.map((curQuad) =>
|
|
quad(
|
|
curQuad.subject,
|
|
curQuad.predicate,
|
|
newSubjectNode,
|
|
curQuad.graph,
|
|
),
|
|
);
|
|
currentObjectQuads.forEach((curQuad) =>
|
|
proxyContext.dataset.delete(curQuad),
|
|
);
|
|
proxyContext.dataset.addAll(newObjectQuads);
|
|
target["@id"] = newSubjectNode;
|
|
}
|
|
addObjectToDataset(
|
|
{ "@id": target["@id"], [key]: value },
|
|
true,
|
|
proxyContext,
|
|
);
|
|
return true;
|
|
},
|
|
deleteProperty(target, key) {
|
|
return deleteValueFromDataset(target, key, proxyContext);
|
|
},
|
|
};
|
|
}
|
|
|