@comunica/bus-query-operation 3.0.3 → 3.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -134,17 +134,7 @@ class ActorQueryOperation extends core_1.Actor {
|
|
|
134
134
|
const operation = (0, Bindings_1.materializeOperation)(expr.input, bindings, bindingsFactory);
|
|
135
135
|
const outputRaw = await mediatorQueryOperation.mediate({ operation, context });
|
|
136
136
|
const output = ActorQueryOperation.getSafeBindings(outputRaw);
|
|
137
|
-
return
|
|
138
|
-
output.bindingsStream.on('end', () => {
|
|
139
|
-
resolve(false);
|
|
140
|
-
});
|
|
141
|
-
output.bindingsStream.on('error', reject);
|
|
142
|
-
output.bindingsStream.on('data', () => {
|
|
143
|
-
output.bindingsStream.close();
|
|
144
|
-
resolve(true);
|
|
145
|
-
});
|
|
146
|
-
})
|
|
147
|
-
.then((exists) => expr.not ? !exists : exists);
|
|
137
|
+
return expr.not !== ((await output.bindingsStream.take(1).toArray()).length === 1);
|
|
148
138
|
};
|
|
149
139
|
}
|
|
150
140
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActorQueryOperation.js","sourceRoot":"","sources":["ActorQueryOperation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BindingsFactory } from '@comunica/bindings-factory';\nimport { KeysInitQuery, KeysQueryOperation } from '@comunica/context-entries';\nimport type { IActorArgs, IActorTest, IAction, Mediate } from '@comunica/core';\nimport { Actor } from '@comunica/core';\nimport { BlankNodeBindingsScoped } from '@comunica/data-factory';\nimport type {\n IQueryOperationResult,\n IQueryOperationResultBindings,\n IQueryOperationResultBoolean,\n IQueryOperationResultQuads,\n IQueryOperationResultVoid,\n Bindings,\n IActionContext,\n FunctionArgumentsCache,\n IQuerySourceWrapper,\n FragmentSelectorShape,\n} from '@comunica/types';\nimport type * as RDF from '@rdfjs/types';\nimport type { Algebra } from 'sparqlalgebrajs';\nimport { materializeOperation } from './Bindings';\n\n/**\n * A counter that keeps track blank node generated through BNODE() SPARQL\n * expressions.\n *\n * @type {number}\n */\nlet bnodeCounter = 0;\n\n/**\n * A comunica actor for query-operation events.\n *\n * Actor types:\n * * Input: IActionQueryOperation: A SPARQL Algebra operation.\n * * Test: <none>\n * * Output: IActorQueryOperationOutput: A bindings stream.\n *\n * @see IActionQueryOperation\n * @see IQueryOperationResult\n */\nexport abstract class ActorQueryOperation extends Actor<IActionQueryOperation, IActorTest, IQueryOperationResult> {\n /**\n * @param args - @defaultNested {<default_bus> a <cbqo:components/BusQueryOperation.jsonld#BusQueryOperation>} bus\n */\n protected constructor(args: IActorQueryOperationArgs) {\n super(args);\n }\n\n /**\n * Safely cast a query operation output to a bindings output.\n * This will throw a runtime error if the output is of the incorrect type.\n * @param {IQueryOperationResult} output A query operation output.\n * @return {IQueryOperationResultBindings} A bindings query operation output.\n */\n public static getSafeBindings(output: IQueryOperationResult): IQueryOperationResultBindings {\n ActorQueryOperation.validateQueryOutput(output, 'bindings');\n return <IQueryOperationResultBindings> output;\n }\n\n /**\n * Safely cast a query operation output to a quads output.\n * This will throw a runtime error if the output is of the incorrect type.\n * @param {IQueryOperationResult} output A query operation output.\n * @return {IQueryOperationResultQuads} A quads query operation output.\n */\n public static getSafeQuads(output: IQueryOperationResult): IQueryOperationResultQuads {\n ActorQueryOperation.validateQueryOutput(output, 'quads');\n return <IQueryOperationResultQuads> output;\n }\n\n /**\n * Safely cast a query operation output to a boolean output.\n * This will throw a runtime error if the output is of the incorrect type.\n * @param {IQueryOperationResult} output A query operation output.\n * @return {IQueryOperationResultBoolean} A boolean query operation output.\n */\n public static getSafeBoolean(output: IQueryOperationResult): IQueryOperationResultBoolean {\n ActorQueryOperation.validateQueryOutput(output, 'boolean');\n return <IQueryOperationResultBoolean> output;\n }\n\n /**\n * Safely cast a query operation output to a void output.\n * This will throw a runtime error if the output is of the incorrect type.\n * @param {IQueryOperationResult} output A query operation output.\n * @return {IQueryOperationResultVoid} A void query operation output.\n */\n public static getSafeVoid(output: IQueryOperationResult): IQueryOperationResultVoid {\n ActorQueryOperation.validateQueryOutput(output, 'void');\n return <IQueryOperationResultVoid> output;\n }\n\n /**\n * Throw an error if the output type does not match the expected type.\n * @param {IQueryOperationResult} output A query operation output.\n * @param {string} expectedType The expected output type.\n */\n public static validateQueryOutput(output: IQueryOperationResult, expectedType: IQueryOperationResult['type']): void {\n if (output.type !== expectedType) {\n throw new Error(`Invalid query output type: Expected '${expectedType}' but got '${output.type}'`);\n }\n }\n\n protected static getBaseExpressionContext(context: IActionContext): IBaseExpressionContext {\n const now: Date | undefined = context.get(KeysInitQuery.queryTimestamp);\n const baseIRI: string | undefined = context.get(KeysInitQuery.baseIRI);\n const functionArgumentsCache: FunctionArgumentsCache = context.get(KeysInitQuery.functionArgumentsCache) ?? {};\n\n // Handle two variants of providing extension functions\n if (context.has(KeysInitQuery.extensionFunctionCreator) && context.has(KeysInitQuery.extensionFunctions)) {\n throw new Error('Illegal simultaneous usage of extensionFunctionCreator and extensionFunctions in context');\n }\n let extensionFunctionCreator: ((functionNamedNode: RDF.NamedNode) =>\n ((args: RDF.Term[]) => Promise<RDF.Term>) | undefined) | undefined = context\n .get(KeysInitQuery.extensionFunctionCreator);\n // Convert dictionary-based variant to callback\n const extensionFunctions: (Record<string, (args: RDF.Term[]) => Promise<RDF.Term>>) | undefined = context\n .get(KeysInitQuery.extensionFunctions);\n if (extensionFunctions) {\n extensionFunctionCreator = functionNamedNode => extensionFunctions[functionNamedNode.value];\n }\n\n return { now, baseIRI, extensionFunctionCreator, functionArgumentsCache };\n }\n\n /**\n * Create an options object that can be used to construct a expression-evaluator synchronous evaluator.\n * @param context An action context.\n * @param _mediatorQueryOperation An optional query query operation mediator.\n * If defined, the existence resolver will be defined as `exists`.\n */\n public static getExpressionContext(context: IActionContext, _mediatorQueryOperation?: MediatorQueryOperation):\n ISyncExpressionContext {\n return {\n ...this.getBaseExpressionContext(context),\n bnode: (input?: string) => new BlankNodeBindingsScoped(input ?? `BNODE_${bnodeCounter++}`),\n };\n }\n\n /**\n * Create an options object that can be used to construct a expression-evaluator asynchronous evaluator.\n * @param context An action context.\n * @param mediatorQueryOperation A query query operation mediator for resolving `exists`.\n * @param bindingsFactory The bindings factory.\n */\n public static getAsyncExpressionContext(\n context: IActionContext,\n mediatorQueryOperation: MediatorQueryOperation,\n bindingsFactory: BindingsFactory,\n ):\n IAsyncExpressionContext {\n return {\n ...this.getBaseExpressionContext(context),\n bnode: (input?: string) => Promise.resolve(new BlankNodeBindingsScoped(input ?? `BNODE_${bnodeCounter++}`)),\n exists: ActorQueryOperation.createExistenceResolver(context, mediatorQueryOperation, bindingsFactory),\n };\n }\n\n /**\n * Create an existence resolver for usage within an expression context.\n * @param context An action context.\n * @param mediatorQueryOperation A query operation mediator.\n * @param bindingsFactory The bindings factory.\n */\n public static createExistenceResolver(\n context: IActionContext,\n mediatorQueryOperation: MediatorQueryOperation,\n bindingsFactory: BindingsFactory,\n ):\n (expr: Algebra.ExistenceExpression, bindings: Bindings) => Promise<boolean> {\n return async(expr, bindings) => {\n const operation = materializeOperation(expr.input, bindings, bindingsFactory);\n\n const outputRaw = await mediatorQueryOperation.mediate({ operation, context });\n const output = ActorQueryOperation.getSafeBindings(outputRaw);\n\n return new Promise<boolean>(\n (resolve, reject) => {\n output.bindingsStream.on('end', () => {\n resolve(false);\n });\n\n output.bindingsStream.on('error', reject);\n\n output.bindingsStream.on('data', () => {\n output.bindingsStream.close();\n resolve(true);\n });\n },\n )\n .then((exists: boolean) => expr.not ? !exists : exists);\n };\n }\n\n /**\n * Throw an error if the context contains the readOnly flag.\n * @param context An action context.\n */\n public static throwOnReadOnly(context: IActionContext): void {\n if (context.get(KeysQueryOperation.readOnly)) {\n throw new Error(`Attempted a write operation in read-only mode`);\n }\n }\n\n /**\n * Obtain the query source attached to the given operation.\n * @param operation An algebra operation.\n */\n public static getOperationSource(operation: Algebra.Operation): IQuerySourceWrapper | undefined {\n return <IQuerySourceWrapper> operation.metadata?.scopedSource;\n }\n\n /**\n * Assign a source wrapper to the given operation.\n * The operation is copied and returned.\n * @param operation An operation.\n * @param source A source wrapper.\n */\n public static assignOperationSource<O extends Algebra.Operation>(operation: O, source: IQuerySourceWrapper): O {\n operation = { ...operation };\n operation.metadata = operation.metadata ? { ...operation.metadata } : {};\n operation.metadata.scopedSource = source;\n return operation;\n }\n\n /**\n * Remove the source wrapper from the given operation.\n * The operation is mutated.\n * @param operation An operation.\n */\n public static removeOperationSource(operation: Algebra.Operation): void {\n delete operation.metadata?.scopedSource;\n if (operation.metadata && Object.keys(operation.metadata).length === 0) {\n delete operation.metadata;\n }\n }\n\n /**\n * Check if the given shape accepts the given query operation.\n * @param shape A shape to test the query operation against.\n * @param operation A query operation to test.\n * @param options Additional options to consider.\n * @param options.joinBindings If additional bindings will be pushed down to the source for joining.\n * @param options.filterBindings If additional bindings will be pushed down to the source for filtering.\n */\n public static doesShapeAcceptOperation(\n shape: FragmentSelectorShape,\n operation: Algebra.Operation,\n options?: {\n joinBindings?: boolean;\n filterBindings?: boolean;\n },\n ): boolean {\n if (shape.type === 'conjunction') {\n return shape.children.every(child => ActorQueryOperation.doesShapeAcceptOperation(child, operation, options));\n }\n if (shape.type === 'disjunction') {\n return shape.children.some(child => ActorQueryOperation.doesShapeAcceptOperation(child, operation, options));\n }\n if (shape.type === 'arity') {\n return ActorQueryOperation.doesShapeAcceptOperation(shape.child, operation, options);\n }\n\n if ((options?.joinBindings && !shape.joinBindings) ?? (options?.filterBindings && !shape.filterBindings)) {\n return false;\n }\n\n if (shape.operation.operationType === 'type') {\n return shape.operation.type === 'project' || shape.operation.type === operation.type;\n }\n return shape.operation.pattern.type === operation.type;\n }\n}\n\nexport interface IActionQueryOperation extends IAction {\n /**\n * The query operation to handle.\n */\n operation: Algebra.Operation;\n}\n\nexport type IActorQueryOperationArgs = IActorArgs<IActionQueryOperation, IActorTest, IQueryOperationResult>;\n\nexport type MediatorQueryOperation = Mediate<IActionQueryOperation, IQueryOperationResult>;\n\nexport interface IBaseExpressionContext {\n now?: Date;\n baseIRI?: string;\n extensionFunctionCreator?: (functionNamedNode: RDF.NamedNode) =>\n ((args: RDF.Term[]) => Promise<RDF.Term>) | undefined;\n functionArgumentsCache?: FunctionArgumentsCache;\n}\n\nexport interface ISyncExpressionContext extends IBaseExpressionContext {\n bnode: (input?: string | undefined) => RDF.BlankNode;\n}\n\nexport interface IAsyncExpressionContext extends IBaseExpressionContext {\n bnode: (input?: string | undefined) => Promise<RDF.BlankNode>;\n exists?: (expr: Algebra.ExistenceExpression, bindings: Bindings) => Promise<boolean>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ActorQueryOperation.js","sourceRoot":"","sources":["ActorQueryOperation.ts"],"names":[],"mappings":";;;AACA,+DAA8E;AAE9E,yCAAuC;AACvC,yDAAiE;AAejE,yCAAkD;AAElD;;;;;GAKG;AACH,IAAI,YAAY,GAAG,CAAC,CAAC;AAErB;;;;;;;;;;GAUG;AACH,MAAsB,mBAAoB,SAAQ,YAA+D;IAC/G;;OAEG;IACH,YAAsB,IAA8B;QAClD,KAAK,CAAC,IAAI,CAAC,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,eAAe,CAAC,MAA6B;QACzD,mBAAmB,CAAC,mBAAmB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAC5D,OAAuC,MAAM,CAAC;IAChD,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,YAAY,CAAC,MAA6B;QACtD,mBAAmB,CAAC,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACzD,OAAoC,MAAM,CAAC;IAC7C,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,cAAc,CAAC,MAA6B;QACxD,mBAAmB,CAAC,mBAAmB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAC3D,OAAsC,MAAM,CAAC;IAC/C,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,WAAW,CAAC,MAA6B;QACrD,mBAAmB,CAAC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACxD,OAAmC,MAAM,CAAC;IAC5C,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,mBAAmB,CAAC,MAA6B,EAAE,YAA2C;QAC1G,IAAI,MAAM,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,wCAAwC,YAAY,cAAc,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC;QACpG,CAAC;IACH,CAAC;IAES,MAAM,CAAC,wBAAwB,CAAC,OAAuB;QAC/D,MAAM,GAAG,GAAqB,OAAO,CAAC,GAAG,CAAC,+BAAa,CAAC,cAAc,CAAC,CAAC;QACxE,MAAM,OAAO,GAAuB,OAAO,CAAC,GAAG,CAAC,+BAAa,CAAC,OAAO,CAAC,CAAC;QACvE,MAAM,sBAAsB,GAA2B,OAAO,CAAC,GAAG,CAAC,+BAAa,CAAC,sBAAsB,CAAC,IAAI,EAAE,CAAC;QAE/G,uDAAuD;QACvD,IAAI,OAAO,CAAC,GAAG,CAAC,+BAAa,CAAC,wBAAwB,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,+BAAa,CAAC,kBAAkB,CAAC,EAAE,CAAC;YACzG,MAAM,IAAI,KAAK,CAAC,0FAA0F,CAAC,CAAC;QAC9G,CAAC;QACD,IAAI,wBAAwB,GACyC,OAAO;aACzE,GAAG,CAAC,+BAAa,CAAC,wBAAwB,CAAC,CAAC;QAC/C,+CAA+C;QAC/C,MAAM,kBAAkB,GAA0E,OAAO;aACtG,GAAG,CAAC,+BAAa,CAAC,kBAAkB,CAAC,CAAC;QACzC,IAAI,kBAAkB,EAAE,CAAC;YACvB,wBAAwB,GAAG,iBAAiB,CAAC,EAAE,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAC9F,CAAC;QAED,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,CAAC;IAC5E,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,oBAAoB,CAAC,OAAuB,EAAE,uBAAgD;QAE1G,OAAO;YACL,GAAG,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC;YACzC,KAAK,EAAE,CAAC,KAAc,EAAE,EAAE,CAAC,IAAI,sCAAuB,CAAC,KAAK,IAAI,SAAS,YAAY,EAAE,EAAE,CAAC;SAC3F,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,yBAAyB,CACrC,OAAuB,EACvB,sBAA8C,EAC9C,eAAgC;QAGhC,OAAO;YACL,GAAG,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC;YACzC,KAAK,EAAE,CAAC,KAAc,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,sCAAuB,CAAC,KAAK,IAAI,SAAS,YAAY,EAAE,EAAE,CAAC,CAAC;YAC3G,MAAM,EAAE,mBAAmB,CAAC,uBAAuB,CAAC,OAAO,EAAE,sBAAsB,EAAE,eAAe,CAAC;SACtG,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,uBAAuB,CACnC,OAAuB,EACvB,sBAA8C,EAC9C,eAAgC;QAGhC,OAAO,KAAK,EAAC,IAAI,EAAE,QAAQ,EAAE,EAAE;YAC7B,MAAM,SAAS,GAAG,IAAA,+BAAoB,EAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;YAE9E,MAAM,SAAS,GAAG,MAAM,sBAAsB,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;YAC/E,MAAM,MAAM,GAAG,mBAAmB,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;YAC9D,OAAO,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC;QACrF,CAAC,CAAC;IACJ,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,eAAe,CAAC,OAAuB;QACnD,IAAI,OAAO,CAAC,GAAG,CAAC,oCAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7C,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,kBAAkB,CAAC,SAA4B;QAC3D,OAA6B,SAAS,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChE,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,qBAAqB,CAA8B,SAAY,EAAE,MAA2B;QACxG,SAAS,GAAG,EAAE,GAAG,SAAS,EAAE,CAAC;QAC7B,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzE,SAAS,CAAC,QAAQ,CAAC,YAAY,GAAG,MAAM,CAAC;QACzC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,qBAAqB,CAAC,SAA4B;QAC9D,OAAO,SAAS,CAAC,QAAQ,EAAE,YAAY,CAAC;QACxC,IAAI,SAAS,CAAC,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvE,OAAO,SAAS,CAAC,QAAQ,CAAC;QAC5B,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CAAC,wBAAwB,CACpC,KAA4B,EAC5B,SAA4B,EAC5B,OAGC;QAED,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YACjC,OAAO,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAAC,wBAAwB,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;QAChH,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YACjC,OAAO,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAAC,wBAAwB,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;QAC/G,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC3B,OAAO,mBAAmB,CAAC,wBAAwB,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QACvF,CAAC;QAED,IAAI,CAAC,OAAO,EAAE,YAAY,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC;YACzG,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,KAAK,CAAC,SAAS,CAAC,aAAa,KAAK,MAAM,EAAE,CAAC;YAC7C,OAAO,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,CAAC;QACvF,CAAC;QACD,OAAO,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,CAAC;IACzD,CAAC;CACF;AAzND,kDAyNC","sourcesContent":["import type { BindingsFactory } from '@comunica/bindings-factory';\nimport { KeysInitQuery, KeysQueryOperation } from '@comunica/context-entries';\nimport type { IActorArgs, IActorTest, IAction, Mediate } from '@comunica/core';\nimport { Actor } from '@comunica/core';\nimport { BlankNodeBindingsScoped } from '@comunica/data-factory';\nimport type {\n IQueryOperationResult,\n IQueryOperationResultBindings,\n IQueryOperationResultBoolean,\n IQueryOperationResultQuads,\n IQueryOperationResultVoid,\n Bindings,\n IActionContext,\n FunctionArgumentsCache,\n IQuerySourceWrapper,\n FragmentSelectorShape,\n} from '@comunica/types';\nimport type * as RDF from '@rdfjs/types';\nimport type { Algebra } from 'sparqlalgebrajs';\nimport { materializeOperation } from './Bindings';\n\n/**\n * A counter that keeps track blank node generated through BNODE() SPARQL\n * expressions.\n *\n * @type {number}\n */\nlet bnodeCounter = 0;\n\n/**\n * A comunica actor for query-operation events.\n *\n * Actor types:\n * * Input: IActionQueryOperation: A SPARQL Algebra operation.\n * * Test: <none>\n * * Output: IActorQueryOperationOutput: A bindings stream.\n *\n * @see IActionQueryOperation\n * @see IQueryOperationResult\n */\nexport abstract class ActorQueryOperation extends Actor<IActionQueryOperation, IActorTest, IQueryOperationResult> {\n /**\n * @param args - @defaultNested {<default_bus> a <cbqo:components/BusQueryOperation.jsonld#BusQueryOperation>} bus\n */\n protected constructor(args: IActorQueryOperationArgs) {\n super(args);\n }\n\n /**\n * Safely cast a query operation output to a bindings output.\n * This will throw a runtime error if the output is of the incorrect type.\n * @param {IQueryOperationResult} output A query operation output.\n * @return {IQueryOperationResultBindings} A bindings query operation output.\n */\n public static getSafeBindings(output: IQueryOperationResult): IQueryOperationResultBindings {\n ActorQueryOperation.validateQueryOutput(output, 'bindings');\n return <IQueryOperationResultBindings> output;\n }\n\n /**\n * Safely cast a query operation output to a quads output.\n * This will throw a runtime error if the output is of the incorrect type.\n * @param {IQueryOperationResult} output A query operation output.\n * @return {IQueryOperationResultQuads} A quads query operation output.\n */\n public static getSafeQuads(output: IQueryOperationResult): IQueryOperationResultQuads {\n ActorQueryOperation.validateQueryOutput(output, 'quads');\n return <IQueryOperationResultQuads> output;\n }\n\n /**\n * Safely cast a query operation output to a boolean output.\n * This will throw a runtime error if the output is of the incorrect type.\n * @param {IQueryOperationResult} output A query operation output.\n * @return {IQueryOperationResultBoolean} A boolean query operation output.\n */\n public static getSafeBoolean(output: IQueryOperationResult): IQueryOperationResultBoolean {\n ActorQueryOperation.validateQueryOutput(output, 'boolean');\n return <IQueryOperationResultBoolean> output;\n }\n\n /**\n * Safely cast a query operation output to a void output.\n * This will throw a runtime error if the output is of the incorrect type.\n * @param {IQueryOperationResult} output A query operation output.\n * @return {IQueryOperationResultVoid} A void query operation output.\n */\n public static getSafeVoid(output: IQueryOperationResult): IQueryOperationResultVoid {\n ActorQueryOperation.validateQueryOutput(output, 'void');\n return <IQueryOperationResultVoid> output;\n }\n\n /**\n * Throw an error if the output type does not match the expected type.\n * @param {IQueryOperationResult} output A query operation output.\n * @param {string} expectedType The expected output type.\n */\n public static validateQueryOutput(output: IQueryOperationResult, expectedType: IQueryOperationResult['type']): void {\n if (output.type !== expectedType) {\n throw new Error(`Invalid query output type: Expected '${expectedType}' but got '${output.type}'`);\n }\n }\n\n protected static getBaseExpressionContext(context: IActionContext): IBaseExpressionContext {\n const now: Date | undefined = context.get(KeysInitQuery.queryTimestamp);\n const baseIRI: string | undefined = context.get(KeysInitQuery.baseIRI);\n const functionArgumentsCache: FunctionArgumentsCache = context.get(KeysInitQuery.functionArgumentsCache) ?? {};\n\n // Handle two variants of providing extension functions\n if (context.has(KeysInitQuery.extensionFunctionCreator) && context.has(KeysInitQuery.extensionFunctions)) {\n throw new Error('Illegal simultaneous usage of extensionFunctionCreator and extensionFunctions in context');\n }\n let extensionFunctionCreator: ((functionNamedNode: RDF.NamedNode) =>\n ((args: RDF.Term[]) => Promise<RDF.Term>) | undefined) | undefined = context\n .get(KeysInitQuery.extensionFunctionCreator);\n // Convert dictionary-based variant to callback\n const extensionFunctions: (Record<string, (args: RDF.Term[]) => Promise<RDF.Term>>) | undefined = context\n .get(KeysInitQuery.extensionFunctions);\n if (extensionFunctions) {\n extensionFunctionCreator = functionNamedNode => extensionFunctions[functionNamedNode.value];\n }\n\n return { now, baseIRI, extensionFunctionCreator, functionArgumentsCache };\n }\n\n /**\n * Create an options object that can be used to construct a expression-evaluator synchronous evaluator.\n * @param context An action context.\n * @param _mediatorQueryOperation An optional query query operation mediator.\n * If defined, the existence resolver will be defined as `exists`.\n */\n public static getExpressionContext(context: IActionContext, _mediatorQueryOperation?: MediatorQueryOperation):\n ISyncExpressionContext {\n return {\n ...this.getBaseExpressionContext(context),\n bnode: (input?: string) => new BlankNodeBindingsScoped(input ?? `BNODE_${bnodeCounter++}`),\n };\n }\n\n /**\n * Create an options object that can be used to construct a expression-evaluator asynchronous evaluator.\n * @param context An action context.\n * @param mediatorQueryOperation A query query operation mediator for resolving `exists`.\n * @param bindingsFactory The bindings factory.\n */\n public static getAsyncExpressionContext(\n context: IActionContext,\n mediatorQueryOperation: MediatorQueryOperation,\n bindingsFactory: BindingsFactory,\n ):\n IAsyncExpressionContext {\n return {\n ...this.getBaseExpressionContext(context),\n bnode: (input?: string) => Promise.resolve(new BlankNodeBindingsScoped(input ?? `BNODE_${bnodeCounter++}`)),\n exists: ActorQueryOperation.createExistenceResolver(context, mediatorQueryOperation, bindingsFactory),\n };\n }\n\n /**\n * Create an existence resolver for usage within an expression context.\n * @param context An action context.\n * @param mediatorQueryOperation A query operation mediator.\n * @param bindingsFactory The bindings factory.\n */\n public static createExistenceResolver(\n context: IActionContext,\n mediatorQueryOperation: MediatorQueryOperation,\n bindingsFactory: BindingsFactory,\n ):\n (expr: Algebra.ExistenceExpression, bindings: Bindings) => Promise<boolean> {\n return async(expr, bindings) => {\n const operation = materializeOperation(expr.input, bindings, bindingsFactory);\n\n const outputRaw = await mediatorQueryOperation.mediate({ operation, context });\n const output = ActorQueryOperation.getSafeBindings(outputRaw);\n return expr.not !== ((await output.bindingsStream.take(1).toArray()).length === 1);\n };\n }\n\n /**\n * Throw an error if the context contains the readOnly flag.\n * @param context An action context.\n */\n public static throwOnReadOnly(context: IActionContext): void {\n if (context.get(KeysQueryOperation.readOnly)) {\n throw new Error(`Attempted a write operation in read-only mode`);\n }\n }\n\n /**\n * Obtain the query source attached to the given operation.\n * @param operation An algebra operation.\n */\n public static getOperationSource(operation: Algebra.Operation): IQuerySourceWrapper | undefined {\n return <IQuerySourceWrapper> operation.metadata?.scopedSource;\n }\n\n /**\n * Assign a source wrapper to the given operation.\n * The operation is copied and returned.\n * @param operation An operation.\n * @param source A source wrapper.\n */\n public static assignOperationSource<O extends Algebra.Operation>(operation: O, source: IQuerySourceWrapper): O {\n operation = { ...operation };\n operation.metadata = operation.metadata ? { ...operation.metadata } : {};\n operation.metadata.scopedSource = source;\n return operation;\n }\n\n /**\n * Remove the source wrapper from the given operation.\n * The operation is mutated.\n * @param operation An operation.\n */\n public static removeOperationSource(operation: Algebra.Operation): void {\n delete operation.metadata?.scopedSource;\n if (operation.metadata && Object.keys(operation.metadata).length === 0) {\n delete operation.metadata;\n }\n }\n\n /**\n * Check if the given shape accepts the given query operation.\n * @param shape A shape to test the query operation against.\n * @param operation A query operation to test.\n * @param options Additional options to consider.\n * @param options.joinBindings If additional bindings will be pushed down to the source for joining.\n * @param options.filterBindings If additional bindings will be pushed down to the source for filtering.\n */\n public static doesShapeAcceptOperation(\n shape: FragmentSelectorShape,\n operation: Algebra.Operation,\n options?: {\n joinBindings?: boolean;\n filterBindings?: boolean;\n },\n ): boolean {\n if (shape.type === 'conjunction') {\n return shape.children.every(child => ActorQueryOperation.doesShapeAcceptOperation(child, operation, options));\n }\n if (shape.type === 'disjunction') {\n return shape.children.some(child => ActorQueryOperation.doesShapeAcceptOperation(child, operation, options));\n }\n if (shape.type === 'arity') {\n return ActorQueryOperation.doesShapeAcceptOperation(shape.child, operation, options);\n }\n\n if ((options?.joinBindings && !shape.joinBindings) ?? (options?.filterBindings && !shape.filterBindings)) {\n return false;\n }\n\n if (shape.operation.operationType === 'type') {\n return shape.operation.type === 'project' || shape.operation.type === operation.type;\n }\n return shape.operation.pattern.type === operation.type;\n }\n}\n\nexport interface IActionQueryOperation extends IAction {\n /**\n * The query operation to handle.\n */\n operation: Algebra.Operation;\n}\n\nexport type IActorQueryOperationArgs = IActorArgs<IActionQueryOperation, IActorTest, IQueryOperationResult>;\n\nexport type MediatorQueryOperation = Mediate<IActionQueryOperation, IQueryOperationResult>;\n\nexport interface IBaseExpressionContext {\n now?: Date;\n baseIRI?: string;\n extensionFunctionCreator?: (functionNamedNode: RDF.NamedNode) =>\n ((args: RDF.Term[]) => Promise<RDF.Term>) | undefined;\n functionArgumentsCache?: FunctionArgumentsCache;\n}\n\nexport interface ISyncExpressionContext extends IBaseExpressionContext {\n bnode: (input?: string | undefined) => RDF.BlankNode;\n}\n\nexport interface IAsyncExpressionContext extends IBaseExpressionContext {\n bnode: (input?: string | undefined) => Promise<RDF.BlankNode>;\n exists?: (expr: Algebra.ExistenceExpression, bindings: Bindings) => Promise<boolean>;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@comunica/bus-query-operation",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.2",
|
|
4
4
|
"description": "A comunica bus for query-operation events.",
|
|
5
5
|
"lsd:module": true,
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,17 +31,17 @@
|
|
|
31
31
|
"lib/**/*.js.map"
|
|
32
32
|
],
|
|
33
33
|
"scripts": {
|
|
34
|
-
"build": "
|
|
34
|
+
"build": "yarn run build:ts && yarn run build:components",
|
|
35
35
|
"build:ts": "node \"../../node_modules/typescript/bin/tsc\"",
|
|
36
36
|
"build:components": "componentsjs-generator"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@comunica/bindings-factory": "^3.0
|
|
40
|
-
"@comunica/context-entries": "^3.0
|
|
41
|
-
"@comunica/core": "^3.0
|
|
42
|
-
"@comunica/data-factory": "^3.0
|
|
43
|
-
"@comunica/metadata": "^3.0
|
|
44
|
-
"@comunica/types": "^3.0
|
|
39
|
+
"@comunica/bindings-factory": "^3.1.0",
|
|
40
|
+
"@comunica/context-entries": "^3.1.0",
|
|
41
|
+
"@comunica/core": "^3.1.0",
|
|
42
|
+
"@comunica/data-factory": "^3.1.0",
|
|
43
|
+
"@comunica/metadata": "^3.1.0",
|
|
44
|
+
"@comunica/types": "^3.1.0",
|
|
45
45
|
"@rdfjs/types": "*",
|
|
46
46
|
"asynciterator": "^3.9.0",
|
|
47
47
|
"rdf-data-factory": "^1.1.2",
|
|
@@ -49,5 +49,5 @@
|
|
|
49
49
|
"rdf-terms": "^1.11.0",
|
|
50
50
|
"sparqlalgebrajs": "^4.3.3"
|
|
51
51
|
},
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "db31677bdef5400194783048840c147e04b793e5"
|
|
53
53
|
}
|