parent
227c94b94f
commit
f799b155e2
@ -0,0 +1,41 @@ |
|||||||
|
import type { GraphNode, PredicateNode, SubjectNode } from "@ldo/rdf-utils"; |
||||||
|
import type { RawObject, RawValue } from "../util/RawObject"; |
||||||
|
import { WildcardObjectSetProxy } from "./WildcardObjectSetProxy"; |
||||||
|
import { addObjectToDataset } from "../util/addObjectToDataset"; |
||||||
|
import type { ProxyContext } from "../ProxyContext"; |
||||||
|
|
||||||
|
export type ObjectSetProxyQuadMatch = [ |
||||||
|
SubjectNode, |
||||||
|
PredicateNode, |
||||||
|
undefined | null, |
||||||
|
GraphNode | undefined | null, |
||||||
|
]; |
||||||
|
|
||||||
|
export class ObjectSetProxy< |
||||||
|
T extends NonNullable<RawValue>, |
||||||
|
> extends WildcardObjectSetProxy<T> { |
||||||
|
protected quadMatch: ObjectSetProxyQuadMatch; |
||||||
|
|
||||||
|
constructor(context: ProxyContext, quadMatch: ObjectSetProxyQuadMatch) { |
||||||
|
super(context, quadMatch); |
||||||
|
this.quadMatch = quadMatch; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Appends a new element with a specified value to the end of the Set. |
||||||
|
*/ |
||||||
|
add(value: T): this { |
||||||
|
addObjectToDataset( |
||||||
|
{ |
||||||
|
"@id": this.quadMatch[0], |
||||||
|
[this.context.contextUtil.iriToKey( |
||||||
|
this.quadMatch[1].value, |
||||||
|
this.context.getRdfType(this.quadMatch[0]), |
||||||
|
)]: value, |
||||||
|
} as RawObject, |
||||||
|
false, |
||||||
|
this.context, |
||||||
|
); |
||||||
|
return this; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,39 @@ |
|||||||
|
import type { GraphNode, ObjectNode, PredicateNode } from "@ldo/rdf-utils"; |
||||||
|
import type { RawObject } from "../util/RawObject"; |
||||||
|
import { addObjectToDataset } from "../util/addObjectToDataset"; |
||||||
|
import type { ProxyContext } from "../ProxyContext"; |
||||||
|
import { WildcardSubjectSetProxy } from "./WildcardSubjectSetProxy"; |
||||||
|
import { _getUnderlyingNode } from "../types"; |
||||||
|
import { quad } from "@rdfjs/data-model"; |
||||||
|
|
||||||
|
export type SubjectSetProxyQuadMatch = [ |
||||||
|
undefined | null, |
||||||
|
PredicateNode, |
||||||
|
ObjectNode, |
||||||
|
GraphNode | undefined | null, |
||||||
|
]; |
||||||
|
|
||||||
|
export class SubjectSetProxy< |
||||||
|
T extends RawObject, |
||||||
|
> extends WildcardSubjectSetProxy<T> { |
||||||
|
protected quadMatch: SubjectSetProxyQuadMatch; |
||||||
|
|
||||||
|
constructor(context: ProxyContext, quadMatch: SubjectSetProxyQuadMatch) { |
||||||
|
super(context, quadMatch); |
||||||
|
this.quadMatch = quadMatch; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Appends a new element with a specified value to the end of the Set. |
||||||
|
*/ |
||||||
|
add(value: T): this { |
||||||
|
const added = addObjectToDataset(value as RawObject, false, this.context); |
||||||
|
const addedNode = added[_getUnderlyingNode]; |
||||||
|
this.context.writeGraphs.forEach((graph) => { |
||||||
|
this.context.dataset.add( |
||||||
|
quad(addedNode, this.quadMatch[1], this.quadMatch[2], graph), |
||||||
|
); |
||||||
|
}); |
||||||
|
return this; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,117 @@ |
|||||||
|
import type { |
||||||
|
SubjectNode, |
||||||
|
PredicateNode, |
||||||
|
ObjectNode, |
||||||
|
GraphNode, |
||||||
|
} from "@ldo/rdf-utils"; |
||||||
|
import type { Dataset, Quad } from "@rdfjs/types"; |
||||||
|
import type { RawValue } from "../util/RawObject"; |
||||||
|
import { SetProxy } from "./setProxy"; |
||||||
|
import type { ProxyContext } from "../ProxyContext"; |
||||||
|
import { getNodeFromRawValue } from "../util/getNodeFromRaw"; |
||||||
|
|
||||||
|
export type WildcardObjectSetProxyQuadMatch = [ |
||||||
|
SubjectNode | undefined | null, |
||||||
|
PredicateNode | undefined | null, |
||||||
|
undefined | null, |
||||||
|
GraphNode | undefined | null, |
||||||
|
]; |
||||||
|
|
||||||
|
/** |
||||||
|
* A WildcardObjectProxy represents a set of nodes in a dataset that are all the |
||||||
|
* object of a given subject and predicate. Because this is a wildcard, the |
||||||
|
* subject and predicate don't necissarily need to be defined. |
||||||
|
*/ |
||||||
|
export class WildcardObjectSetProxy< |
||||||
|
T extends NonNullable<RawValue>, |
||||||
|
> extends SetProxy<T> { |
||||||
|
protected quadMatch: WildcardObjectSetProxyQuadMatch; |
||||||
|
|
||||||
|
constructor( |
||||||
|
context: ProxyContext, |
||||||
|
quadMatch: WildcardObjectSetProxyQuadMatch, |
||||||
|
) { |
||||||
|
super(context, quadMatch); |
||||||
|
this.quadMatch = quadMatch; |
||||||
|
} |
||||||
|
|
||||||
|
protected getSPO(value?: T | undefined): { |
||||||
|
subject?: SubjectNode; |
||||||
|
predicate?: PredicateNode; |
||||||
|
object?: ObjectNode; |
||||||
|
} { |
||||||
|
// Get the RDF Node that represents the value, skip is no value
|
||||||
|
const subject = this.quadMatch[0] ?? undefined; |
||||||
|
const predicate = this.quadMatch[1] ?? undefined; |
||||||
|
if (value) { |
||||||
|
// Get datatype if applicable
|
||||||
|
let datatype: string | undefined = undefined; |
||||||
|
if (this.quadMatch[0] && predicate) { |
||||||
|
const rdfType = this.context.getRdfType(this.quadMatch[0]); |
||||||
|
const key = this.context.contextUtil.iriToKey(predicate.value, rdfType); |
||||||
|
datatype = this.context.contextUtil.getDataType(key, rdfType); |
||||||
|
} |
||||||
|
const valueNode = getNodeFromRawValue(value, this.context, datatype); |
||||||
|
return { |
||||||
|
subject, |
||||||
|
predicate, |
||||||
|
object: valueNode, |
||||||
|
}; |
||||||
|
} |
||||||
|
// SPO for no value
|
||||||
|
return { |
||||||
|
subject, |
||||||
|
predicate, |
||||||
|
object: undefined, |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
protected getNodeOfFocus(quad: Quad): ObjectNode { |
||||||
|
return quad.object as ObjectNode; |
||||||
|
} |
||||||
|
|
||||||
|
private manuallyMatchWithUnknownObjectNode( |
||||||
|
subject: SubjectNode | undefined, |
||||||
|
predicate: PredicateNode | undefined, |
||||||
|
value: T, |
||||||
|
): Dataset<Quad, Quad> { |
||||||
|
// If there's not an object, that means that we don't know the object node
|
||||||
|
// and need to find it manually.
|
||||||
|
const matchingQuads = this.context.dataset.match(subject, predicate, null); |
||||||
|
return matchingQuads.filter( |
||||||
|
(quad) => |
||||||
|
quad.object.termType === "Literal" && quad.object.value === value, |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
delete(value: T): boolean { |
||||||
|
const { dataset } = this.context; |
||||||
|
const { subject, predicate, object } = this.getSPO(value); |
||||||
|
if (!object) { |
||||||
|
const matchedQuads = this.manuallyMatchWithUnknownObjectNode( |
||||||
|
subject, |
||||||
|
predicate, |
||||||
|
value, |
||||||
|
); |
||||||
|
matchedQuads.forEach((quad) => dataset.delete(quad)); |
||||||
|
return matchedQuads.size > 0; |
||||||
|
} else { |
||||||
|
const willDelete = dataset.match(subject, predicate, object).size > 0; |
||||||
|
dataset.deleteMatches(subject, predicate, object); |
||||||
|
return willDelete; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
has(value: T): boolean { |
||||||
|
const { dataset } = this.context; |
||||||
|
const { subject, predicate, object } = this.getSPO(value); |
||||||
|
if (!object) { |
||||||
|
return ( |
||||||
|
this.manuallyMatchWithUnknownObjectNode(subject, predicate, value) |
||||||
|
.size > 0 |
||||||
|
); |
||||||
|
} else { |
||||||
|
return dataset.match(subject, predicate, object).size > 0; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,63 @@ |
|||||||
|
import type { |
||||||
|
SubjectNode, |
||||||
|
PredicateNode, |
||||||
|
ObjectNode, |
||||||
|
GraphNode, |
||||||
|
} from "@ldo/rdf-utils"; |
||||||
|
import type { Quad } from "@rdfjs/types"; |
||||||
|
import type { RawObject } from "../util/RawObject"; |
||||||
|
import { SetProxy } from "./setProxy"; |
||||||
|
import type { ProxyContext } from "../ProxyContext"; |
||||||
|
import { getNodeFromRawObject } from "../util/getNodeFromRaw"; |
||||||
|
|
||||||
|
export type WildcardSubjectSetProxyQuadMatch = [ |
||||||
|
undefined | null, |
||||||
|
PredicateNode | undefined | null, |
||||||
|
ObjectNode | undefined | null, |
||||||
|
GraphNode | undefined | null, |
||||||
|
]; |
||||||
|
|
||||||
|
/** |
||||||
|
* A WildcardObjectProxy represents a set of nodes in a dataset that are all the |
||||||
|
* object of a given subject and predicate. Because this is a wildcard, the |
||||||
|
* subject and predicate don't necissarily need to be defined. |
||||||
|
*/ |
||||||
|
export class WildcardSubjectSetProxy<T extends RawObject> extends SetProxy<T> { |
||||||
|
protected quadMatch: WildcardSubjectSetProxyQuadMatch; |
||||||
|
|
||||||
|
constructor( |
||||||
|
context: ProxyContext, |
||||||
|
quadMatch: WildcardSubjectSetProxyQuadMatch, |
||||||
|
) { |
||||||
|
super(context, quadMatch); |
||||||
|
this.quadMatch = quadMatch; |
||||||
|
} |
||||||
|
|
||||||
|
protected getSPO(value?: T | undefined): { |
||||||
|
subject?: SubjectNode; |
||||||
|
predicate?: PredicateNode; |
||||||
|
object?: ObjectNode; |
||||||
|
} { |
||||||
|
// Get the RDF Node that represents the value, skip is no value
|
||||||
|
const predicate = this.quadMatch[1] ?? undefined; |
||||||
|
const object = this.quadMatch[2] ?? undefined; |
||||||
|
if (value) { |
||||||
|
const valueNode = getNodeFromRawObject(value, this.context.contextUtil); |
||||||
|
return { |
||||||
|
subject: valueNode, |
||||||
|
predicate, |
||||||
|
object, |
||||||
|
}; |
||||||
|
} |
||||||
|
// SPO for no value
|
||||||
|
return { |
||||||
|
subject: undefined, |
||||||
|
predicate, |
||||||
|
object, |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
protected getNodeOfFocus(quad: Quad): SubjectNode { |
||||||
|
return quad.subject as SubjectNode; |
||||||
|
} |
||||||
|
} |
@ -1,177 +0,0 @@ |
|||||||
import { quad } from "@rdfjs/data-model"; |
|
||||||
import type { NamedNode } from "@rdfjs/types"; |
|
||||||
import type { ObjectNode, QuadMatch, SubjectNode } from "@ldo/rdf-utils"; |
|
||||||
import type { ObjectJsonRepresentation } from "../util/nodeToJsonldRepresentation"; |
|
||||||
import { nodeToJsonldRepresentation } from "../util/nodeToJsonldRepresentation"; |
|
||||||
import type { ArrayMethodBuildersType } from "./arrayMethods"; |
|
||||||
import { arrayMethodsBuilders, methodNames } from "./arrayMethods"; |
|
||||||
import { |
|
||||||
_getNodeAtIndex, |
|
||||||
_getUnderlyingArrayTarget, |
|
||||||
_getUnderlyingDataset, |
|
||||||
_getUnderlyingMatch, |
|
||||||
_isSubjectOriented, |
|
||||||
_proxyContext, |
|
||||||
} from "../types"; |
|
||||||
import { modifyArray } from "./modifyArray"; |
|
||||||
import type { ProxyContext } from "../ProxyContext"; |
|
||||||
import { NodeSet } from "../util/NodeSet"; |
|
||||||
import { filterQuadsByLanguageOrdering } from "../language/languageUtils"; |
|
||||||
|
|
||||||
export type ArrayProxyTarget = [ |
|
||||||
quadMatch: QuadMatch, |
|
||||||
curArray: ObjectNode[], |
|
||||||
isSubjectOriented?: boolean, |
|
||||||
isLangStringArray?: boolean, |
|
||||||
]; |
|
||||||
|
|
||||||
function updateArrayOrder( |
|
||||||
target: ArrayProxyTarget, |
|
||||||
proxyContext: ProxyContext, |
|
||||||
): void { |
|
||||||
let quads = proxyContext.dataset.match(...target[0]); |
|
||||||
if (target[3]) { |
|
||||||
// Is lang string array
|
|
||||||
quads = filterQuadsByLanguageOrdering(quads, proxyContext.languageOrdering); |
|
||||||
} |
|
||||||
const datasetObjects = new NodeSet(); |
|
||||||
quads.toArray().forEach((quad) => { |
|
||||||
// If this this a subject-oriented document
|
|
||||||
if (target[2]) { |
|
||||||
datasetObjects.add(quad.subject as SubjectNode); |
|
||||||
} else { |
|
||||||
datasetObjects.add(quad.object as ObjectNode); |
|
||||||
} |
|
||||||
}); |
|
||||||
const processedObjects: ObjectNode[] = []; |
|
||||||
target[1].forEach((arrItem) => { |
|
||||||
if (datasetObjects.has(arrItem)) { |
|
||||||
processedObjects.push(arrItem); |
|
||||||
datasetObjects.delete(arrItem); |
|
||||||
} |
|
||||||
}); |
|
||||||
datasetObjects.toArray().forEach((datasetObject) => { |
|
||||||
processedObjects.push(datasetObject); |
|
||||||
}); |
|
||||||
target[1] = processedObjects; |
|
||||||
} |
|
||||||
|
|
||||||
function getProcessedArray( |
|
||||||
target: ArrayProxyTarget, |
|
||||||
proxyContext: ProxyContext, |
|
||||||
): ObjectJsonRepresentation[] { |
|
||||||
return target[1].map((node) => { |
|
||||||
return nodeToJsonldRepresentation(node, proxyContext); |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
export function createArrayHandler( |
|
||||||
proxyContext: ProxyContext, |
|
||||||
): ProxyHandler<ArrayProxyTarget> { |
|
||||||
return { |
|
||||||
get(target, key, ...rest) { |
|
||||||
switch (key) { |
|
||||||
case _getUnderlyingDataset: |
|
||||||
return proxyContext.dataset; |
|
||||||
case _getUnderlyingMatch: |
|
||||||
return target[0]; |
|
||||||
case _isSubjectOriented: |
|
||||||
return target[2]; |
|
||||||
case _getUnderlyingArrayTarget: |
|
||||||
return target; |
|
||||||
case _proxyContext: |
|
||||||
return proxyContext; |
|
||||||
case _getNodeAtIndex: |
|
||||||
return (index: number): ObjectNode | undefined => { |
|
||||||
updateArrayOrder(target, proxyContext); |
|
||||||
return target[1][index]; |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
// TODO: Because of this, every get operation is O(n). Consider changing
|
|
||||||
// this
|
|
||||||
updateArrayOrder(target, proxyContext); |
|
||||||
const processedArray = getProcessedArray(target, proxyContext); |
|
||||||
if (methodNames.has(key as keyof ArrayMethodBuildersType)) { |
|
||||||
return arrayMethodsBuilders[key as keyof ArrayMethodBuildersType]( |
|
||||||
target, |
|
||||||
key as string, |
|
||||||
proxyContext, |
|
||||||
); |
|
||||||
} |
|
||||||
return Reflect.get(processedArray, key, ...rest); |
|
||||||
}, |
|
||||||
getOwnPropertyDescriptor(target, key, ...rest) { |
|
||||||
updateArrayOrder(target, proxyContext); |
|
||||||
const processedArray = getProcessedArray(target, proxyContext); |
|
||||||
return Reflect.getOwnPropertyDescriptor(processedArray, key, ...rest); |
|
||||||
}, |
|
||||||
ownKeys(target, ...rest) { |
|
||||||
updateArrayOrder(target, proxyContext); |
|
||||||
const processedArray = getProcessedArray(target, proxyContext); |
|
||||||
return Reflect.ownKeys(processedArray, ...rest); |
|
||||||
}, |
|
||||||
getPrototypeOf(target, ...rest) { |
|
||||||
updateArrayOrder(target, proxyContext); |
|
||||||
const processedObjects = getProcessedArray(target, proxyContext); |
|
||||||
return Reflect.getPrototypeOf(processedObjects, ...rest); |
|
||||||
}, |
|
||||||
has(target, ...rest) { |
|
||||||
updateArrayOrder(target, proxyContext); |
|
||||||
const processedObjects = getProcessedArray(target, proxyContext); |
|
||||||
return Reflect.has(processedObjects, ...rest); |
|
||||||
}, |
|
||||||
set(target, key, value, ...rest) { |
|
||||||
if (key === _proxyContext) { |
|
||||||
proxyContext = value; |
|
||||||
return true; |
|
||||||
} |
|
||||||
updateArrayOrder(target, proxyContext); |
|
||||||
if (typeof key !== "symbol" && !isNaN(parseInt(key as string))) { |
|
||||||
const index = parseInt(key); |
|
||||||
return modifyArray( |
|
||||||
{ |
|
||||||
target, |
|
||||||
key, |
|
||||||
toAdd: [value], |
|
||||||
quadsToDelete(allQuads) { |
|
||||||
return allQuads[index] ? [allQuads[index]] : []; |
|
||||||
}, |
|
||||||
modifyCoreArray(coreArray, addedValues) { |
|
||||||
coreArray[index] = addedValues[0]; |
|
||||||
return true; |
|
||||||
}, |
|
||||||
}, |
|
||||||
proxyContext, |
|
||||||
); |
|
||||||
} |
|
||||||
return Reflect.set(target[1], key, ...rest); |
|
||||||
}, |
|
||||||
deleteProperty(target, key) { |
|
||||||
const { dataset } = proxyContext; |
|
||||||
if (typeof key !== "symbol" && !isNaN(parseInt(key as string))) { |
|
||||||
const objectQuad = dataset.match(...target[0]).toArray()[parseInt(key)]; |
|
||||||
if (!objectQuad) { |
|
||||||
return true; |
|
||||||
} |
|
||||||
const term = target[2] ? objectQuad.subject : objectQuad.object; |
|
||||||
if (term.termType === "Literal") { |
|
||||||
const subject = target[0][0] as NamedNode; |
|
||||||
const predicate = target[0][1] as NamedNode; |
|
||||||
if (subject && predicate) { |
|
||||||
dataset.delete(quad(subject, predicate, term)); |
|
||||||
} |
|
||||||
return true; |
|
||||||
} else if ( |
|
||||||
term.termType === "NamedNode" || |
|
||||||
term.termType === "BlankNode" |
|
||||||
) { |
|
||||||
dataset.deleteMatches(term, undefined, undefined); |
|
||||||
dataset.deleteMatches(undefined, undefined, term); |
|
||||||
return true; |
|
||||||
} |
|
||||||
} |
|
||||||
return true; |
|
||||||
}, |
|
||||||
}; |
|
||||||
} |
|
@ -1,141 +0,0 @@ |
|||||||
import { defaultGraph } from "@rdfjs/data-model"; |
|
||||||
import type { Quad } from "@rdfjs/types"; |
|
||||||
import type { ObjectNode } from "@ldo/rdf-utils"; |
|
||||||
import { |
|
||||||
TransactionDataset, |
|
||||||
createTransactionDatasetFactory, |
|
||||||
} from "@ldo/subscribable-dataset"; |
|
||||||
import { createDatasetFactory } from "@ldo/dataset"; |
|
||||||
import type { ProxyContext } from "../ProxyContext"; |
|
||||||
import { addObjectToDataset } from "../util/addObjectToDataset"; |
|
||||||
import { |
|
||||||
getNodeFromRawObject, |
|
||||||
getNodeFromRawValue, |
|
||||||
} from "../util/getNodeFromRaw"; |
|
||||||
import { nodeToString } from "../util/NodeSet"; |
|
||||||
import type { ObjectJsonRepresentation } from "../util/nodeToJsonldRepresentation"; |
|
||||||
import type { RawObject, RawValue } from "../util/RawObject"; |
|
||||||
import type { ArrayProxyTarget } from "./createSetHandler"; |
|
||||||
|
|
||||||
export function checkArrayModification( |
|
||||||
target: ArrayProxyTarget, |
|
||||||
objectsToAdd: RawValue[], |
|
||||||
proxyContext: ProxyContext, |
|
||||||
) { |
|
||||||
if (target[2]) { |
|
||||||
for (const objectToAdd of objectsToAdd) { |
|
||||||
// Undefined is fine no matter what
|
|
||||||
if (objectToAdd === undefined) { |
|
||||||
return; |
|
||||||
} |
|
||||||
if (typeof objectToAdd !== "object") { |
|
||||||
throw new Error( |
|
||||||
`Cannot add a literal "${objectToAdd}"(${typeof objectToAdd}) to a subject-oriented collection.`, |
|
||||||
); |
|
||||||
} |
|
||||||
// Create a test dataset to see if the inputted data is valid
|
|
||||||
const testDataset = new TransactionDataset( |
|
||||||
proxyContext.dataset, |
|
||||||
createDatasetFactory(), |
|
||||||
createTransactionDatasetFactory(), |
|
||||||
); |
|
||||||
addObjectToDataset( |
|
||||||
objectToAdd as RawObject, |
|
||||||
false, |
|
||||||
proxyContext.duplicate({ |
|
||||||
writeGraphs: [defaultGraph()], |
|
||||||
}), |
|
||||||
); |
|
||||||
const isValidAddition = |
|
||||||
testDataset.match( |
|
||||||
getNodeFromRawObject(objectToAdd, proxyContext.contextUtil), |
|
||||||
target[0][1], |
|
||||||
target[0][2], |
|
||||||
).size !== 0; |
|
||||||
if (!isValidAddition) { |
|
||||||
throw new Error( |
|
||||||
`Cannot add value to collection. This must contain a quad that matches (${nodeToString( |
|
||||||
target[0][0], |
|
||||||
)}, ${nodeToString(target[0][1])}, ${nodeToString( |
|
||||||
target[0][2], |
|
||||||
)}, ${nodeToString(target[0][3])})`,
|
|
||||||
); |
|
||||||
} |
|
||||||
} |
|
||||||
} else if (!target[0][0] || !target[0][1]) { |
|
||||||
throw new Error( |
|
||||||
"A collection that does not specify a match for both a subject or predicate cannot be modified directly.", |
|
||||||
); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
export function modifyArray<ReturnType>( |
|
||||||
config: { |
|
||||||
target: ArrayProxyTarget; |
|
||||||
key: string; |
|
||||||
toAdd?: RawValue[]; |
|
||||||
quadsToDelete?: (quads: Quad[]) => Quad[]; |
|
||||||
modifyCoreArray: ( |
|
||||||
coreArray: ArrayProxyTarget[1], |
|
||||||
addedValues: ArrayProxyTarget[1], |
|
||||||
) => ReturnType; |
|
||||||
}, |
|
||||||
proxyContext: ProxyContext, |
|
||||||
): ReturnType { |
|
||||||
const { target, toAdd, quadsToDelete, modifyCoreArray, key } = config; |
|
||||||
const { dataset, contextUtil } = proxyContext; |
|
||||||
checkArrayModification(target, toAdd || [], proxyContext); |
|
||||||
|
|
||||||
// Remove appropriate Quads
|
|
||||||
if (quadsToDelete) { |
|
||||||
const quadArr = dataset.match(...target[0]).toArray(); |
|
||||||
const deleteQuadArr = quadsToDelete(quadArr); |
|
||||||
// Filter out overlapping items
|
|
||||||
deleteQuadArr.forEach((delQuad) => { |
|
||||||
if (target[2]) { |
|
||||||
dataset.deleteMatches(delQuad.subject, undefined, undefined); |
|
||||||
} else { |
|
||||||
dataset.delete(delQuad); |
|
||||||
} |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
// Add new items to the dataset
|
|
||||||
const added = toAdd |
|
||||||
?.map((item) => { |
|
||||||
return typeof item === "object" |
|
||||||
? addObjectToDataset(item, false, proxyContext) |
|
||||||
: item; |
|
||||||
}) |
|
||||||
.filter( |
|
||||||
(val) => val != undefined, |
|
||||||
) as NonNullable<ObjectJsonRepresentation>[]; |
|
||||||
if (!target[2] && target[0][0] && target[0][1] && added) { |
|
||||||
addObjectToDataset( |
|
||||||
{ |
|
||||||
"@id": target[0][0], |
|
||||||
[contextUtil.iriToKey( |
|
||||||
target[0][1].value, |
|
||||||
proxyContext.getRdfType(target[0][0]), |
|
||||||
)]: added, |
|
||||||
} as RawObject, |
|
||||||
false, |
|
||||||
proxyContext, |
|
||||||
); |
|
||||||
} |
|
||||||
const addedNodes = added |
|
||||||
? (added |
|
||||||
.map((addedValue) => { |
|
||||||
return getNodeFromRawValue( |
|
||||||
key, |
|
||||||
addedValue, |
|
||||||
target[0][0] ? proxyContext.getRdfType(target[0][0]) : [], |
|
||||||
proxyContext, |
|
||||||
); |
|
||||||
}) |
|
||||||
.filter((val) => val != undefined) as ObjectNode[]) |
|
||||||
: []; |
|
||||||
|
|
||||||
// Allow the base array to be modified
|
|
||||||
return modifyCoreArray(target[1], addedNodes); |
|
||||||
} |
|
Loading…
Reference in new issue