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.
110 lines
3.6 KiB
110 lines
3.6 KiB
import type { GraphNode, QuadMatch } from "@ldo/rdf-utils";
|
|
import type { BlankNode, Dataset, NamedNode } from "@rdfjs/types";
|
|
import type { ArrayProxyTarget } from "./arrayProxy/createArrayHandler";
|
|
import { createArrayHandler } from "./arrayProxy/createArrayHandler";
|
|
import { createSubjectHandler } from "./subjectProxy/createSubjectHandler";
|
|
import type { SubjectProxy } from "./subjectProxy/SubjectProxy";
|
|
import type { ArrayProxy } from "./arrayProxy/ArrayProxy";
|
|
import { _getUnderlyingArrayTarget } from "./types";
|
|
import type { ContextUtil } from "./ContextUtil";
|
|
import type { LanguageOrdering } from "./language/languageTypes";
|
|
|
|
export interface ProxyContextOptions {
|
|
dataset: Dataset;
|
|
contextUtil: ContextUtil;
|
|
writeGraphs: GraphNode[];
|
|
languageOrdering: LanguageOrdering;
|
|
prefilledArrayTargets?: ArrayProxyTarget[];
|
|
state?: Record<string, unknown>;
|
|
}
|
|
|
|
/**
|
|
* This file keeps track of the target objects used in the proxies.
|
|
* The reason is so that JSON.stringify does not recurse inifinitely
|
|
* when it encounters a circular object.
|
|
*/
|
|
export class ProxyContext {
|
|
private subjectMap: Map<string, SubjectProxy> = new Map();
|
|
private arrayMap: Map<string, ArrayProxy> = new Map();
|
|
|
|
readonly dataset: Dataset;
|
|
readonly contextUtil: ContextUtil;
|
|
readonly writeGraphs: GraphNode[];
|
|
readonly languageOrdering: LanguageOrdering;
|
|
public state: Record<string, unknown>;
|
|
|
|
constructor(options: ProxyContextOptions) {
|
|
this.dataset = options.dataset;
|
|
this.contextUtil = options.contextUtil;
|
|
this.writeGraphs = options.writeGraphs;
|
|
this.languageOrdering = options.languageOrdering;
|
|
this.state = options.state || {};
|
|
if (options.prefilledArrayTargets) {
|
|
options.prefilledArrayTargets.forEach((target) => {
|
|
this.createArrayProxy(target[0], target[2], target);
|
|
});
|
|
}
|
|
}
|
|
|
|
public createSubjectProxy(node: NamedNode | BlankNode): SubjectProxy {
|
|
if (!this.subjectMap.has(node.value)) {
|
|
const proxy = new Proxy(
|
|
{ "@id": node },
|
|
this.createSubjectHandler(),
|
|
) as unknown as SubjectProxy;
|
|
this.subjectMap.set(node.value, proxy);
|
|
}
|
|
return this.subjectMap.get(node.value) as SubjectProxy;
|
|
}
|
|
|
|
protected createSubjectHandler() {
|
|
return createSubjectHandler(this);
|
|
}
|
|
|
|
private getArrayKey(...quadMatch: QuadMatch) {
|
|
return `${quadMatch[0]?.value || "undefined"}|${
|
|
quadMatch[1]?.value || "undefined"
|
|
}|${quadMatch[2]?.value || "undefined"}|${
|
|
quadMatch[3]?.value || "undefined"
|
|
}`;
|
|
}
|
|
|
|
public createArrayProxy(
|
|
quadMatch: QuadMatch,
|
|
isSubjectOriented = false,
|
|
initialTarget?: ArrayProxyTarget,
|
|
isLangStringArray?: boolean,
|
|
): ArrayProxy {
|
|
const key = this.getArrayKey(...quadMatch);
|
|
if (!this.arrayMap.has(key)) {
|
|
const proxy = new Proxy(
|
|
initialTarget || [quadMatch, [], isSubjectOriented, isLangStringArray],
|
|
this.createArrayHandler(),
|
|
) as unknown as ArrayProxy;
|
|
this.arrayMap.set(key, proxy);
|
|
}
|
|
return this.arrayMap.get(key) as ArrayProxy;
|
|
}
|
|
|
|
protected createArrayHandler() {
|
|
return createArrayHandler(this);
|
|
}
|
|
|
|
public duplicate(alternativeOptions: Partial<ProxyContextOptions>) {
|
|
const prefilledArrayTargets: ArrayProxyTarget[] = [];
|
|
this.arrayMap.forEach((value) => {
|
|
prefilledArrayTargets.push(value[_getUnderlyingArrayTarget]);
|
|
});
|
|
const fullOptions: ProxyContextOptions = {
|
|
...{
|
|
dataset: this.dataset,
|
|
contextUtil: this.contextUtil,
|
|
writeGraphs: this.writeGraphs,
|
|
languageOrdering: this.languageOrdering,
|
|
prefilledArrayTargets,
|
|
},
|
|
...alternativeOptions,
|
|
};
|
|
return new ProxyContext(fullOptions);
|
|
}
|
|
}
|
|
|