@comunica/actor-rdf-join-inner-multi-bind 3.2.2 → 3.2.4-alpha.47.0

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.
@@ -11,7 +11,13 @@
11
11
  "@type": "Class",
12
12
  "requireElement": "ActorRdfJoinMultiBind",
13
13
  "extends": [
14
- "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin"
14
+ {
15
+ "@type": "GenericComponentExtension",
16
+ "component": "cbrj:components/ActorRdfJoin.jsonld#ActorRdfJoin",
17
+ "genericTypeInstances": [
18
+ "carjimb:components/ActorRdfJoinMultiBind.jsonld#IActorRdfJoinMultiBindTestSideData"
19
+ ]
20
+ }
15
21
  ],
16
22
  "comment": "A comunica Multi-way Bind RDF Join Actor.",
17
23
  "parameters": [
@@ -41,15 +47,7 @@
41
47
  },
42
48
  {
43
49
  "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind_args_minMaxCardinalityRatio",
44
- "range": {
45
- "@type": "ParameterRangeUnion",
46
- "parameterRangeElements": [
47
- "xsd:double",
48
- {
49
- "@type": "ParameterRangeUndefined"
50
- }
51
- ]
52
- },
50
+ "range": "xsd:double",
53
51
  "default": "60",
54
52
  "comment": "The number of times the smallest cardinality should fit in the maximum cardinality."
55
53
  },
@@ -101,6 +99,10 @@
101
99
  {
102
100
  "@type": "ParameterRangeGenericTypeReference",
103
101
  "parameterRangeGenericType": "npmd:@comunica/actor-abstract-mediatyped/^3.0.0/components/ActorAbstractMediaTyped.jsonld#ActorAbstractMediaTyped__generic_O"
102
+ },
103
+ {
104
+ "@type": "ParameterRangeGenericTypeReference",
105
+ "parameterRangeGenericType": "npmd:@comunica/actor-abstract-mediatyped/^3.0.0/components/ActorAbstractMediaTyped.jsonld#ActorAbstractMediaTyped__generic_TS"
104
106
  }
105
107
  ]
106
108
  },
@@ -115,6 +117,10 @@
115
117
  {
116
118
  "@type": "ParameterRangeGenericTypeReference",
117
119
  "parameterRangeGenericType": "npmd:@comunica/actor-abstract-mediatyped/^3.0.0/components/ActorAbstractMediaTyped.jsonld#ActorAbstractMediaTyped__generic_O"
120
+ },
121
+ {
122
+ "@type": "ParameterRangeGenericTypeReference",
123
+ "parameterRangeGenericType": "npmd:@comunica/actor-abstract-mediatyped/^3.0.0/components/ActorAbstractMediaTyped.jsonld#ActorAbstractMediaTyped__generic_TS"
118
124
  }
119
125
  ]
120
126
  },
@@ -124,6 +130,20 @@
124
130
  },
125
131
  "comment": "The bus this actor subscribes to."
126
132
  },
133
+ {
134
+ "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind_args_busFailMessage",
135
+ "range": {
136
+ "@type": "ParameterRangeUnion",
137
+ "parameterRangeElements": [
138
+ "xsd:string",
139
+ {
140
+ "@type": "ParameterRangeUndefined"
141
+ }
142
+ ]
143
+ },
144
+ "default": "RDF joining failed: none of the configured actors were able to handle the join type ${action.type}",
145
+ "comment": "The message that will be configured in the bus for reporting failures. This message may be a template string that contains references to the executed `action`. For example, the following templated string is allowed: \"RDF dereferencing failed: no actors could handle ${action.handle.mediaType}\""
146
+ },
127
147
  {
128
148
  "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind_args_beforeActors",
129
149
  "range": {
@@ -146,6 +166,10 @@
146
166
  {
147
167
  "@type": "ParameterRangeGenericTypeReference",
148
168
  "parameterRangeGenericType": "npmd:@comunica/actor-abstract-mediatyped/^3.0.0/components/ActorAbstractMediaTyped.jsonld#ActorAbstractMediaTyped__generic_O"
169
+ },
170
+ {
171
+ "@type": "ParameterRangeGenericTypeReference",
172
+ "parameterRangeGenericType": "npmd:@comunica/actor-abstract-mediatyped/^3.0.0/components/ActorAbstractMediaTyped.jsonld#ActorAbstractMediaTyped__generic_TS"
149
173
  }
150
174
  ]
151
175
  }
@@ -201,13 +225,6 @@
201
225
  "memberFieldName": "mediatorMergeBindingsContext",
202
226
  "range": "cc:components/Mediator.jsonld#Mediator"
203
227
  },
204
- {
205
- "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind__member_FACTORY",
206
- "memberFieldName": "FACTORY",
207
- "range": {
208
- "@type": "ParameterRangeWildcard"
209
- }
210
- },
211
228
  {
212
229
  "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind__member_constructor",
213
230
  "memberFieldName": "constructor"
@@ -287,6 +304,12 @@
287
304
  "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind_args_bus"
288
305
  }
289
306
  },
307
+ {
308
+ "keyRaw": "busFailMessage",
309
+ "value": {
310
+ "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind_args_busFailMessage"
311
+ }
312
+ },
290
313
  {
291
314
  "keyRaw": "beforeActors",
292
315
  "value": {
@@ -302,7 +325,13 @@
302
325
  "@type": "AbstractClass",
303
326
  "requireElement": "IActorRdfJoinMultiBindArgs",
304
327
  "extends": [
305
- "cbrj:components/ActorRdfJoin.jsonld#IActorRdfJoinArgs"
328
+ {
329
+ "@type": "GenericComponentExtension",
330
+ "component": "cbrj:components/ActorRdfJoin.jsonld#IActorRdfJoinArgs",
331
+ "genericTypeInstances": [
332
+ "carjimb:components/ActorRdfJoinMultiBind.jsonld#IActorRdfJoinMultiBindTestSideData"
333
+ ]
334
+ }
306
335
  ],
307
336
  "parameters": [],
308
337
  "memberFields": [
@@ -332,6 +361,26 @@
332
361
  }
333
362
  ],
334
363
  "constructorArguments": []
364
+ },
365
+ {
366
+ "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#IActorRdfJoinMultiBindTestSideData",
367
+ "@type": "AbstractClass",
368
+ "requireElement": "IActorRdfJoinMultiBindTestSideData",
369
+ "extends": [
370
+ "cbrj:components/ActorRdfJoin.jsonld#IActorRdfJoinTestSideData"
371
+ ],
372
+ "parameters": [],
373
+ "memberFields": [
374
+ {
375
+ "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#IActorRdfJoinMultiBindTestSideData__member_entriesUnsorted",
376
+ "memberFieldName": "entriesUnsorted"
377
+ },
378
+ {
379
+ "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#IActorRdfJoinMultiBindTestSideData__member_entriesSorted",
380
+ "memberFieldName": "entriesSorted"
381
+ }
382
+ ],
383
+ "constructorArguments": []
335
384
  }
336
385
  ]
337
386
  }
@@ -35,6 +35,9 @@
35
35
  "args_bus": {
36
36
  "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind_args_bus"
37
37
  },
38
+ "args_busFailMessage": {
39
+ "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind_args_busFailMessage"
40
+ },
38
41
  "args_beforeActors": {
39
42
  "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind_args_beforeActors",
40
43
  "@container": "@list"
@@ -66,6 +69,9 @@
66
69
  "bus": {
67
70
  "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind_args_bus"
68
71
  },
72
+ "busFailMessage": {
73
+ "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind_args_busFailMessage"
74
+ },
69
75
  "beforeActors": {
70
76
  "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#ActorRdfJoinMultiBind_args_beforeActors",
71
77
  "@container": "@list"
@@ -76,6 +82,11 @@
76
82
  "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#IActorRdfJoinMultiBindArgs",
77
83
  "@prefix": true,
78
84
  "@context": {}
85
+ },
86
+ "IActorRdfJoinMultiBindTestSideData": {
87
+ "@id": "carjimb:components/ActorRdfJoinMultiBind.jsonld#IActorRdfJoinMultiBindTestSideData",
88
+ "@prefix": true,
89
+ "@context": {}
79
90
  }
80
91
  }
81
92
  ]
@@ -1,23 +1,23 @@
1
- import { BindingsFactory } from '@comunica/bindings-factory';
2
1
  import type { MediatorMergeBindingsContext } from '@comunica/bus-merge-bindings-context';
3
2
  import type { MediatorQueryOperation } from '@comunica/bus-query-operation';
4
- import type { IActionRdfJoin, IActorRdfJoinOutputInner, IActorRdfJoinArgs } from '@comunica/bus-rdf-join';
3
+ import type { IActionRdfJoin, IActorRdfJoinOutputInner, IActorRdfJoinArgs, IActorRdfJoinTestSideData } from '@comunica/bus-rdf-join';
5
4
  import { ActorRdfJoin } from '@comunica/bus-rdf-join';
6
5
  import type { MediatorRdfJoinEntriesSort } from '@comunica/bus-rdf-join-entries-sort';
6
+ import type { TestResult } from '@comunica/core';
7
7
  import type { IMediatorTypeJoinCoefficients } from '@comunica/mediatortype-join-coefficients';
8
- import type { Bindings, BindingsStream, MetadataBindings } from '@comunica/types';
8
+ import type { Bindings, BindingsStream, IJoinEntryWithMetadata } from '@comunica/types';
9
+ import { BindingsFactory } from '@comunica/utils-bindings-factory';
9
10
  import { Factory, Algebra } from 'sparqlalgebrajs';
10
11
  /**
11
12
  * A comunica Multi-way Bind RDF Join Actor.
12
13
  */
13
- export declare class ActorRdfJoinMultiBind extends ActorRdfJoin {
14
+ export declare class ActorRdfJoinMultiBind extends ActorRdfJoin<IActorRdfJoinMultiBindTestSideData> {
14
15
  readonly bindOrder: BindOrder;
15
16
  readonly selectivityModifier: number;
16
17
  readonly minMaxCardinalityRatio: number;
17
18
  readonly mediatorJoinEntriesSort: MediatorRdfJoinEntriesSort;
18
19
  readonly mediatorQueryOperation: MediatorQueryOperation;
19
20
  readonly mediatorMergeBindingsContext: MediatorMergeBindingsContext;
20
- static readonly FACTORY: Factory;
21
21
  constructor(args: IActorRdfJoinMultiBindArgs);
22
22
  /**
23
23
  * Create a new bindings stream that takes every binding of the base stream
@@ -30,12 +30,12 @@ export declare class ActorRdfJoinMultiBind extends ActorRdfJoin {
30
30
  * @param optional If the original bindings should be emitted when the resulting bindings stream is empty.
31
31
  * @return {BindingsStream}
32
32
  */
33
- static createBindStream(bindOrder: BindOrder, baseStream: BindingsStream, operations: Algebra.Operation[], operationBinder: (boundOperations: Algebra.Operation[], operationBindings: Bindings) => Promise<BindingsStream>, optional: boolean, bindingsFactory: BindingsFactory): BindingsStream;
34
- getOutput(action: IActionRdfJoin): Promise<IActorRdfJoinOutputInner>;
33
+ static createBindStream(bindOrder: BindOrder, baseStream: BindingsStream, operations: Algebra.Operation[], operationBinder: (boundOperations: Algebra.Operation[], operationBindings: Bindings) => Promise<BindingsStream>, optional: boolean, algebraFactory: Factory, bindingsFactory: BindingsFactory): BindingsStream;
34
+ getOutput(action: IActionRdfJoin, sideData: IActorRdfJoinMultiBindTestSideData): Promise<IActorRdfJoinOutputInner>;
35
35
  canBindWithOperation(operation: Algebra.Operation): boolean;
36
- getJoinCoefficients(action: IActionRdfJoin, metadatas: MetadataBindings[]): Promise<IMediatorTypeJoinCoefficients>;
36
+ getJoinCoefficients(action: IActionRdfJoin, sideData: IActorRdfJoinTestSideData): Promise<TestResult<IMediatorTypeJoinCoefficients, IActorRdfJoinMultiBindTestSideData>>;
37
37
  }
38
- export interface IActorRdfJoinMultiBindArgs extends IActorRdfJoinArgs {
38
+ export interface IActorRdfJoinMultiBindArgs extends IActorRdfJoinArgs<IActorRdfJoinMultiBindTestSideData> {
39
39
  /**
40
40
  * The order in which elements should be bound
41
41
  * @default {depth-first}
@@ -52,7 +52,7 @@ export interface IActorRdfJoinMultiBindArgs extends IActorRdfJoinArgs {
52
52
  * @range {double}
53
53
  * @default {60}
54
54
  */
55
- minMaxCardinalityRatio?: number;
55
+ minMaxCardinalityRatio: number;
56
56
  /**
57
57
  * The join entries sort mediator
58
58
  */
@@ -67,3 +67,7 @@ export interface IActorRdfJoinMultiBindArgs extends IActorRdfJoinArgs {
67
67
  mediatorMergeBindingsContext: MediatorMergeBindingsContext;
68
68
  }
69
69
  export type BindOrder = 'depth-first' | 'breadth-first';
70
+ export interface IActorRdfJoinMultiBindTestSideData extends IActorRdfJoinTestSideData {
71
+ entriesUnsorted: IJoinEntryWithMetadata[];
72
+ entriesSorted: IJoinEntryWithMetadata[];
73
+ }
@@ -1,10 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ActorRdfJoinMultiBind = void 0;
4
- const bindings_factory_1 = require("@comunica/bindings-factory");
5
- const bus_query_operation_1 = require("@comunica/bus-query-operation");
6
4
  const bus_rdf_join_1 = require("@comunica/bus-rdf-join");
7
5
  const context_entries_1 = require("@comunica/context-entries");
6
+ const core_1 = require("@comunica/core");
7
+ const utils_bindings_factory_1 = require("@comunica/utils-bindings-factory");
8
+ const utils_query_operation_1 = require("@comunica/utils-query-operation");
8
9
  const asynciterator_1 = require("asynciterator");
9
10
  const sparqlalgebrajs_1 = require("sparqlalgebrajs");
10
11
  /**
@@ -12,10 +13,6 @@ const sparqlalgebrajs_1 = require("sparqlalgebrajs");
12
13
  */
13
14
  class ActorRdfJoinMultiBind extends bus_rdf_join_1.ActorRdfJoin {
14
15
  constructor(args) {
15
- // TODO: remove this fallback in the next major update
16
- if (args.minMaxCardinalityRatio === undefined) {
17
- args.minMaxCardinalityRatio = 60;
18
- }
19
16
  super(args, {
20
17
  logicalType: 'inner',
21
18
  physicalName: 'bind',
@@ -34,15 +31,14 @@ class ActorRdfJoinMultiBind extends bus_rdf_join_1.ActorRdfJoin {
34
31
  * @param optional If the original bindings should be emitted when the resulting bindings stream is empty.
35
32
  * @return {BindingsStream}
36
33
  */
37
- static createBindStream(bindOrder, baseStream, operations, operationBinder, optional, bindingsFactory) {
34
+ static createBindStream(bindOrder, baseStream, operations, operationBinder, optional, algebraFactory, bindingsFactory) {
38
35
  // Enable auto-start on sub-bindings during depth-first binding for best performance.
39
36
  const autoStartSubBindings = bindOrder === 'depth-first';
40
37
  // Create bindings function
41
38
  const binder = (bindings) => {
42
39
  // We don't bind the filter because filters are always handled last,
43
40
  // and we need to avoid binding filters of sub-queries, which are to be handled first. (see spec test bind10)
44
- const subOperations = operations
45
- .map(operation => (0, bus_query_operation_1.materializeOperation)(operation, bindings, bindingsFactory, { bindFilter: true }));
41
+ const subOperations = operations.map(operation => (0, utils_query_operation_1.materializeOperation)(operation, bindings, algebraFactory, bindingsFactory, { bindFilter: true }));
46
42
  const bindingsMerger = (subBindings) => subBindings.merge(bindings);
47
43
  return new asynciterator_1.TransformIterator(async () => (await operationBinder(subOperations, bindings))
48
44
  .transform({ map: bindingsMerger }), { maxBufferSize: 128, autoStart: autoStartSubBindings });
@@ -61,11 +57,11 @@ class ActorRdfJoinMultiBind extends bus_rdf_join_1.ActorRdfJoin {
61
57
  throw new Error(`Received request for unknown bind order: ${bindOrder}`);
62
58
  }
63
59
  }
64
- async getOutput(action) {
65
- const bindingsFactory = await bindings_factory_1.BindingsFactory.create(this.mediatorMergeBindingsContext, action.context);
66
- // Order the entries so we can pick the first one (usually the one with the lowest cardinality)
67
- const entriesUnsorted = await bus_rdf_join_1.ActorRdfJoin.getEntriesWithMetadatas(action.entries);
68
- const entries = await bus_rdf_join_1.ActorRdfJoin.sortJoinEntries(this.mediatorJoinEntriesSort, entriesUnsorted, action.context);
60
+ async getOutput(action, sideData) {
61
+ const dataFactory = action.context.getSafe(context_entries_1.KeysInitQuery.dataFactory);
62
+ const algebraFactory = new sparqlalgebrajs_1.Factory(dataFactory);
63
+ const bindingsFactory = await utils_bindings_factory_1.BindingsFactory.create(this.mediatorMergeBindingsContext, action.context, dataFactory);
64
+ const entries = sideData.entriesSorted;
69
65
  this.logDebug(action.context, 'First entry for Bind Join: ', () => ({ entry: entries[0].operation, metadata: entries[0].metadata }));
70
66
  // Close the non-smallest streams
71
67
  for (const [i, element] of entries.entries()) {
@@ -85,10 +81,10 @@ class ActorRdfJoinMultiBind extends bus_rdf_join_1.ActorRdfJoin {
85
81
  // Send the materialized patterns to the mediator for recursive join evaluation.
86
82
  const operation = operations.length === 1 ?
87
83
  operations[0] :
88
- ActorRdfJoinMultiBind.FACTORY.createJoin(operations);
89
- const output = bus_query_operation_1.ActorQueryOperation.getSafeBindings(await this.mediatorQueryOperation.mediate({ operation, context: subContext?.set(context_entries_1.KeysQueryOperation.joinBindings, operationBindings) }));
84
+ algebraFactory.createJoin(operations);
85
+ const output = (0, utils_query_operation_1.getSafeBindings)(await this.mediatorQueryOperation.mediate({ operation, context: subContext?.set(context_entries_1.KeysQueryOperation.joinBindings, operationBindings) }));
90
86
  return output.bindingsStream;
91
- }, false, bindingsFactory);
87
+ }, false, algebraFactory, bindingsFactory);
92
88
  return {
93
89
  result: {
94
90
  type: 'bindings',
@@ -96,7 +92,7 @@ class ActorRdfJoinMultiBind extends bus_rdf_join_1.ActorRdfJoin {
96
92
  metadata: () => this.constructResultMetadata(entries, entries.map(entry => entry.metadata), action.context),
97
93
  },
98
94
  physicalPlanMetadata: {
99
- bindIndex: entriesUnsorted.indexOf(entries[0]),
95
+ bindIndex: sideData.entriesUnsorted.indexOf(entries[0]),
100
96
  bindOperation: entries[0].operation,
101
97
  bindOperationCardinality: entries[0].metadata.cardinality,
102
98
  bindOrder: this.bindOrder,
@@ -117,15 +113,22 @@ class ActorRdfJoinMultiBind extends bus_rdf_join_1.ActorRdfJoin {
117
113
  });
118
114
  return valid;
119
115
  }
120
- async getJoinCoefficients(action, metadatas) {
116
+ async getJoinCoefficients(action, sideData) {
117
+ let { metadatas } = sideData;
121
118
  // Order the entries so we can pick the first one (usually the one with the lowest cardinality)
122
- const entries = await bus_rdf_join_1.ActorRdfJoin.sortJoinEntries(this.mediatorJoinEntriesSort, action.entries
123
- .map((entry, i) => ({ ...entry, metadata: metadatas[i] })), action.context);
124
- metadatas = entries.map(entry => entry.metadata);
119
+ const entriesUnsorted = action.entries
120
+ .map((entry, i) => ({ ...entry, metadata: metadatas[i] }));
121
+ const entriesTest = await bus_rdf_join_1.ActorRdfJoin
122
+ .sortJoinEntries(this.mediatorJoinEntriesSort, entriesUnsorted, action.context);
123
+ if (entriesTest.isFailed()) {
124
+ return entriesTest;
125
+ }
126
+ const entriesSorted = entriesTest.get();
127
+ metadatas = entriesSorted.map(entry => entry.metadata);
125
128
  const requestInitialTimes = bus_rdf_join_1.ActorRdfJoin.getRequestInitialTimes(metadatas);
126
129
  const requestItemTimes = bus_rdf_join_1.ActorRdfJoin.getRequestItemTimes(metadatas);
127
130
  // Determine first stream and remaining ones
128
- const remainingEntries = [...entries];
131
+ const remainingEntries = [...entriesSorted];
129
132
  const remainingRequestInitialTimes = [...requestInitialTimes];
130
133
  const remainingRequestItemTimes = [...requestItemTimes];
131
134
  remainingEntries.splice(0, 1);
@@ -134,22 +137,22 @@ class ActorRdfJoinMultiBind extends bus_rdf_join_1.ActorRdfJoin {
134
137
  // Reject binding on some operation types
135
138
  if (remainingEntries
136
139
  .some(entry => !this.canBindWithOperation(entry.operation))) {
137
- throw new Error(`Actor ${this.name} can not bind on Extend and Group operations`);
140
+ return (0, core_1.failTest)(`Actor ${this.name} can not bind on Extend and Group operations`);
138
141
  }
139
142
  // Reject binding on modified operations, since using the output directly would be significantly more efficient.
140
143
  if (remainingEntries.some(entry => entry.operationModified)) {
141
- throw new Error(`Actor ${this.name} can not be used over remaining entries with modified operations`);
144
+ return (0, core_1.failTest)(`Actor ${this.name} can not be used over remaining entries with modified operations`);
142
145
  }
143
146
  // Only run this actor if the smallest stream is significantly smaller than the largest stream.
144
147
  // We must use Math.max, because the last metadata is not necessarily the biggest, but it's the least preferred.
145
148
  if (metadatas[0].cardinality.value * this.minMaxCardinalityRatio >
146
149
  Math.max(...metadatas.map(metadata => metadata.cardinality.value))) {
147
- throw new Error(`Actor ${this.name} can only run if the smallest stream is much smaller than largest stream`);
150
+ return (0, core_1.failTest)(`Actor ${this.name} can only run if the smallest stream is much smaller than largest stream`);
148
151
  }
149
152
  // Determine selectivities of smallest entry with all other entries
150
153
  const selectivities = await Promise.all(remainingEntries
151
154
  .map(async (entry) => (await this.mediatorJoinSelectivity.mediate({
152
- entries: [entries[0], entry],
155
+ entries: [entriesSorted[0], entry],
153
156
  context: action.context,
154
157
  })).selectivity * this.selectivityModifier));
155
158
  // Determine coefficients for remaining entries
@@ -160,7 +163,7 @@ class ActorRdfJoinMultiBind extends bus_rdf_join_1.ActorRdfJoin {
160
163
  .reduce((sum, element) => sum + element, 0);
161
164
  const receiveItemCostRemaining = remainingRequestItemTimes
162
165
  .reduce((sum, element) => sum + element, 0);
163
- return {
166
+ return (0, core_1.passTestWithSideData)({
164
167
  iterations: metadatas[0].cardinality.value * cardinalityRemaining,
165
168
  persistedItems: 0,
166
169
  blockingItems: 0,
@@ -168,9 +171,8 @@ class ActorRdfJoinMultiBind extends bus_rdf_join_1.ActorRdfJoin {
168
171
  metadatas[0].cardinality.value * (requestItemTimes[0] +
169
172
  receiveInitialCostRemaining +
170
173
  cardinalityRemaining * receiveItemCostRemaining),
171
- };
174
+ }, { ...sideData, entriesUnsorted, entriesSorted });
172
175
  }
173
176
  }
174
177
  exports.ActorRdfJoinMultiBind = ActorRdfJoinMultiBind;
175
- ActorRdfJoinMultiBind.FACTORY = new sparqlalgebrajs_1.Factory();
176
178
  //# sourceMappingURL=ActorRdfJoinMultiBind.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ActorRdfJoinMultiBind.js","sourceRoot":"","sources":["ActorRdfJoinMultiBind.ts"],"names":[],"mappings":"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","sourcesContent":["import { BindingsFactory } from '@comunica/bindings-factory';\nimport type { MediatorMergeBindingsContext } from '@comunica/bus-merge-bindings-context';\nimport type { MediatorQueryOperation } from '@comunica/bus-query-operation';\nimport { ActorQueryOperation, materializeOperation } from '@comunica/bus-query-operation';\nimport type {\n IActionRdfJoin,\n IActorRdfJoinOutputInner,\n IActorRdfJoinArgs,\n} from '@comunica/bus-rdf-join';\nimport { ActorRdfJoin } from '@comunica/bus-rdf-join';\nimport type { MediatorRdfJoinEntriesSort } from '@comunica/bus-rdf-join-entries-sort';\nimport { KeysQueryOperation } from '@comunica/context-entries';\nimport type { IMediatorTypeJoinCoefficients } from '@comunica/mediatortype-join-coefficients';\nimport type { Bindings, BindingsStream, IQueryOperationResultBindings, MetadataBindings } from '@comunica/types';\nimport { MultiTransformIterator, TransformIterator, UnionIterator } from 'asynciterator';\nimport { Factory, Algebra, Util } from 'sparqlalgebrajs';\n\n/**\n * A comunica Multi-way Bind RDF Join Actor.\n */\nexport class ActorRdfJoinMultiBind extends ActorRdfJoin {\n public readonly bindOrder: BindOrder;\n public readonly selectivityModifier: number;\n public readonly minMaxCardinalityRatio: number;\n public readonly mediatorJoinEntriesSort: MediatorRdfJoinEntriesSort;\n public readonly mediatorQueryOperation: MediatorQueryOperation;\n public readonly mediatorMergeBindingsContext: MediatorMergeBindingsContext;\n\n public static readonly FACTORY = new Factory();\n\n public constructor(args: IActorRdfJoinMultiBindArgs) {\n // TODO: remove this fallback in the next major update\n if (args.minMaxCardinalityRatio === undefined) {\n args.minMaxCardinalityRatio = 60;\n }\n super(args, {\n logicalType: 'inner',\n physicalName: 'bind',\n canHandleUndefs: true,\n isLeaf: false,\n });\n }\n\n /**\n * Create a new bindings stream that takes every binding of the base stream\n * and binds it to the remaining patterns, evaluates those patterns, and emits all their bindings.\n *\n * @param bindOrder The order in which elements should be bound.\n * @param baseStream The base stream.\n * @param operations The operations to bind with each binding of the base stream.\n * @param operationBinder A callback to retrieve the bindings stream of bound operations.\n * @param optional If the original bindings should be emitted when the resulting bindings stream is empty.\n * @return {BindingsStream}\n */\n public static createBindStream(\n bindOrder: BindOrder,\n baseStream: BindingsStream,\n operations: Algebra.Operation[],\n operationBinder: (boundOperations: Algebra.Operation[], operationBindings: Bindings)\n => Promise<BindingsStream>,\n optional: boolean,\n bindingsFactory: BindingsFactory,\n ): BindingsStream {\n // Enable auto-start on sub-bindings during depth-first binding for best performance.\n const autoStartSubBindings = bindOrder === 'depth-first';\n\n // Create bindings function\n const binder = (bindings: Bindings): BindingsStream => {\n // We don't bind the filter because filters are always handled last,\n // and we need to avoid binding filters of sub-queries, which are to be handled first. (see spec test bind10)\n const subOperations = operations\n .map(operation => materializeOperation(operation, bindings, bindingsFactory, { bindFilter: true }));\n const bindingsMerger = (subBindings: Bindings): Bindings | undefined => subBindings.merge(bindings);\n return new TransformIterator(async() => (await operationBinder(subOperations, bindings))\n .transform({ map: bindingsMerger }), { maxBufferSize: 128, autoStart: autoStartSubBindings });\n };\n\n // Create an iterator that binds elements from the base stream in different orders\n switch (bindOrder) {\n case 'depth-first':\n return new MultiTransformIterator(baseStream, { autoStart: false, multiTransform: binder, optional });\n case 'breadth-first':\n return new UnionIterator(baseStream.transform({\n map: binder,\n optional,\n }), { autoStart: false });\n default:\n // eslint-disable-next-line ts/restrict-template-expressions\n throw new Error(`Received request for unknown bind order: ${bindOrder}`);\n }\n }\n\n public async getOutput(action: IActionRdfJoin): Promise<IActorRdfJoinOutputInner> {\n const bindingsFactory = await BindingsFactory.create(this.mediatorMergeBindingsContext, action.context);\n\n // Order the entries so we can pick the first one (usually the one with the lowest cardinality)\n const entriesUnsorted = await ActorRdfJoin.getEntriesWithMetadatas(action.entries);\n const entries = await ActorRdfJoin.sortJoinEntries(this.mediatorJoinEntriesSort, entriesUnsorted, action.context);\n\n this.logDebug(\n action.context,\n 'First entry for Bind Join: ',\n () => ({ entry: entries[0].operation, metadata: entries[0].metadata }),\n );\n\n // Close the non-smallest streams\n for (const [ i, element ] of entries.entries()) {\n if (i !== 0) {\n element.output.bindingsStream.close();\n }\n }\n\n // Take the stream with the lowest cardinality\n const smallestStream: IQueryOperationResultBindings = entries[0].output;\n const remainingEntries = [ ...entries ];\n remainingEntries.splice(0, 1);\n\n // Bind the remaining patterns for each binding in the stream\n const subContext = action.context\n .set(KeysQueryOperation.joinLeftMetadata, entries[0].metadata)\n .set(KeysQueryOperation.joinRightMetadatas, remainingEntries.map(entry => entry.metadata));\n const bindingsStream: BindingsStream = ActorRdfJoinMultiBind.createBindStream(\n this.bindOrder,\n smallestStream.bindingsStream,\n remainingEntries.map(entry => entry.operation),\n async(operations: Algebra.Operation[], operationBindings: Bindings) => {\n // Send the materialized patterns to the mediator for recursive join evaluation.\n const operation = operations.length === 1 ?\n operations[0] :\n ActorRdfJoinMultiBind.FACTORY.createJoin(operations);\n const output = ActorQueryOperation.getSafeBindings(await this.mediatorQueryOperation.mediate(\n { operation, context: subContext?.set(KeysQueryOperation.joinBindings, operationBindings) },\n ));\n return output.bindingsStream;\n },\n false,\n bindingsFactory,\n );\n\n return {\n result: {\n type: 'bindings',\n bindingsStream,\n metadata: () => this.constructResultMetadata(entries, entries.map(entry => entry.metadata), action.context),\n },\n physicalPlanMetadata: {\n bindIndex: entriesUnsorted.indexOf(entries[0]),\n bindOperation: entries[0].operation,\n bindOperationCardinality: entries[0].metadata.cardinality,\n bindOrder: this.bindOrder,\n },\n };\n }\n\n public canBindWithOperation(operation: Algebra.Operation): boolean {\n let valid = true;\n Util.recurseOperation(operation, {\n [Algebra.types.EXTEND](): boolean {\n valid = false;\n return false;\n },\n [Algebra.types.GROUP](): boolean {\n valid = false;\n return false;\n },\n });\n\n return valid;\n }\n\n public async getJoinCoefficients(\n action: IActionRdfJoin,\n metadatas: MetadataBindings[],\n ): Promise<IMediatorTypeJoinCoefficients> {\n // Order the entries so we can pick the first one (usually the one with the lowest cardinality)\n const entries = await ActorRdfJoin.sortJoinEntries(this.mediatorJoinEntriesSort, action.entries\n .map((entry, i) => ({ ...entry, metadata: metadatas[i] })), action.context);\n metadatas = entries.map(entry => entry.metadata);\n\n const requestInitialTimes = ActorRdfJoin.getRequestInitialTimes(metadatas);\n const requestItemTimes = ActorRdfJoin.getRequestItemTimes(metadatas);\n\n // Determine first stream and remaining ones\n const remainingEntries = [ ...entries ];\n const remainingRequestInitialTimes = [ ...requestInitialTimes ];\n const remainingRequestItemTimes = [ ...requestItemTimes ];\n remainingEntries.splice(0, 1);\n remainingRequestInitialTimes.splice(0, 1);\n remainingRequestItemTimes.splice(0, 1);\n\n // Reject binding on some operation types\n if (remainingEntries\n .some(entry => !this.canBindWithOperation(entry.operation))) {\n throw new Error(`Actor ${this.name} can not bind on Extend and Group operations`);\n }\n\n // Reject binding on modified operations, since using the output directly would be significantly more efficient.\n if (remainingEntries.some(entry => entry.operationModified)) {\n throw new Error(`Actor ${this.name} can not be used over remaining entries with modified operations`);\n }\n\n // Only run this actor if the smallest stream is significantly smaller than the largest stream.\n // We must use Math.max, because the last metadata is not necessarily the biggest, but it's the least preferred.\n if (metadatas[0].cardinality.value * this.minMaxCardinalityRatio >\n Math.max(...metadatas.map(metadata => metadata.cardinality.value))) {\n throw new Error(`Actor ${this.name} can only run if the smallest stream is much smaller than largest stream`);\n }\n\n // Determine selectivities of smallest entry with all other entries\n const selectivities = await Promise.all(remainingEntries\n .map(async entry => (await this.mediatorJoinSelectivity.mediate({\n entries: [ entries[0], entry ],\n context: action.context,\n })).selectivity * this.selectivityModifier));\n\n // Determine coefficients for remaining entries\n const cardinalityRemaining = remainingEntries\n .map((entry, i) => entry.metadata.cardinality.value * selectivities[i])\n .reduce((sum, element) => sum + element, 0);\n const receiveInitialCostRemaining = remainingRequestInitialTimes\n .reduce((sum, element) => sum + element, 0);\n const receiveItemCostRemaining = remainingRequestItemTimes\n .reduce((sum, element) => sum + element, 0);\n\n return {\n iterations: metadatas[0].cardinality.value * cardinalityRemaining,\n persistedItems: 0,\n blockingItems: 0,\n requestTime: requestInitialTimes[0] +\n metadatas[0].cardinality.value * (\n requestItemTimes[0] +\n receiveInitialCostRemaining +\n cardinalityRemaining * receiveItemCostRemaining\n ),\n };\n }\n}\n\nexport interface IActorRdfJoinMultiBindArgs extends IActorRdfJoinArgs {\n /**\n * The order in which elements should be bound\n * @default {depth-first}\n */\n bindOrder: BindOrder;\n /**\n * Multiplier for selectivity values\n * @range {double}\n * @default {0.0001}\n */\n selectivityModifier: number;\n /**\n * The number of times the smallest cardinality should fit in the maximum cardinality.\n * @range {double}\n * @default {60}\n */\n minMaxCardinalityRatio?: number;\n /**\n * The join entries sort mediator\n */\n mediatorJoinEntriesSort: MediatorRdfJoinEntriesSort;\n /**\n * The query operation mediator\n */\n mediatorQueryOperation: MediatorQueryOperation;\n /**\n * A mediator for creating binding context merge handlers\n */\n mediatorMergeBindingsContext: MediatorMergeBindingsContext;\n}\n\nexport type BindOrder = 'depth-first' | 'breadth-first';\n"]}
1
+ {"version":3,"file":"ActorRdfJoinMultiBind.js","sourceRoot":"","sources":["ActorRdfJoinMultiBind.ts"],"names":[],"mappings":"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","sourcesContent":["import type { MediatorMergeBindingsContext } from '@comunica/bus-merge-bindings-context';\nimport type { MediatorQueryOperation } from '@comunica/bus-query-operation';\nimport type {\n IActionRdfJoin,\n IActorRdfJoinOutputInner,\n IActorRdfJoinArgs,\n IActorRdfJoinTestSideData,\n} from '@comunica/bus-rdf-join';\nimport { ActorRdfJoin } from '@comunica/bus-rdf-join';\nimport type { MediatorRdfJoinEntriesSort } from '@comunica/bus-rdf-join-entries-sort';\nimport { KeysInitQuery, KeysQueryOperation } from '@comunica/context-entries';\nimport type { TestResult } from '@comunica/core';\nimport { passTestWithSideData, failTest } from '@comunica/core';\nimport type { IMediatorTypeJoinCoefficients } from '@comunica/mediatortype-join-coefficients';\nimport type {\n Bindings,\n BindingsStream,\n ComunicaDataFactory,\n IJoinEntryWithMetadata,\n IQueryOperationResultBindings,\n} from '@comunica/types';\nimport { BindingsFactory } from '@comunica/utils-bindings-factory';\nimport { getSafeBindings, materializeOperation } from '@comunica/utils-query-operation';\nimport { MultiTransformIterator, TransformIterator, UnionIterator } from 'asynciterator';\nimport { Factory, Algebra, Util } from 'sparqlalgebrajs';\n\n/**\n * A comunica Multi-way Bind RDF Join Actor.\n */\nexport class ActorRdfJoinMultiBind extends ActorRdfJoin<IActorRdfJoinMultiBindTestSideData> {\n public readonly bindOrder: BindOrder;\n public readonly selectivityModifier: number;\n public readonly minMaxCardinalityRatio: number;\n public readonly mediatorJoinEntriesSort: MediatorRdfJoinEntriesSort;\n public readonly mediatorQueryOperation: MediatorQueryOperation;\n public readonly mediatorMergeBindingsContext: MediatorMergeBindingsContext;\n\n public constructor(args: IActorRdfJoinMultiBindArgs) {\n super(args, {\n logicalType: 'inner',\n physicalName: 'bind',\n canHandleUndefs: true,\n isLeaf: false,\n });\n }\n\n /**\n * Create a new bindings stream that takes every binding of the base stream\n * and binds it to the remaining patterns, evaluates those patterns, and emits all their bindings.\n *\n * @param bindOrder The order in which elements should be bound.\n * @param baseStream The base stream.\n * @param operations The operations to bind with each binding of the base stream.\n * @param operationBinder A callback to retrieve the bindings stream of bound operations.\n * @param optional If the original bindings should be emitted when the resulting bindings stream is empty.\n * @return {BindingsStream}\n */\n public static createBindStream(\n bindOrder: BindOrder,\n baseStream: BindingsStream,\n operations: Algebra.Operation[],\n operationBinder: (boundOperations: Algebra.Operation[], operationBindings: Bindings)\n => Promise<BindingsStream>,\n optional: boolean,\n algebraFactory: Factory,\n bindingsFactory: BindingsFactory,\n ): BindingsStream {\n // Enable auto-start on sub-bindings during depth-first binding for best performance.\n const autoStartSubBindings = bindOrder === 'depth-first';\n\n // Create bindings function\n const binder = (bindings: Bindings): BindingsStream => {\n // We don't bind the filter because filters are always handled last,\n // and we need to avoid binding filters of sub-queries, which are to be handled first. (see spec test bind10)\n const subOperations = operations.map(operation => materializeOperation(\n operation,\n bindings,\n algebraFactory,\n bindingsFactory,\n { bindFilter: true },\n ));\n const bindingsMerger = (subBindings: Bindings): Bindings | undefined => subBindings.merge(bindings);\n return new TransformIterator(async() => (await operationBinder(subOperations, bindings))\n .transform({ map: bindingsMerger }), { maxBufferSize: 128, autoStart: autoStartSubBindings });\n };\n\n // Create an iterator that binds elements from the base stream in different orders\n switch (bindOrder) {\n case 'depth-first':\n return new MultiTransformIterator(baseStream, { autoStart: false, multiTransform: binder, optional });\n case 'breadth-first':\n return new UnionIterator(baseStream.transform({\n map: binder,\n optional,\n }), { autoStart: false });\n default:\n // eslint-disable-next-line ts/restrict-template-expressions\n throw new Error(`Received request for unknown bind order: ${bindOrder}`);\n }\n }\n\n public async getOutput(\n action: IActionRdfJoin,\n sideData: IActorRdfJoinMultiBindTestSideData,\n ): Promise<IActorRdfJoinOutputInner> {\n const dataFactory: ComunicaDataFactory = action.context.getSafe(KeysInitQuery.dataFactory);\n const algebraFactory = new Factory(dataFactory);\n const bindingsFactory = await BindingsFactory.create(\n this.mediatorMergeBindingsContext,\n action.context,\n dataFactory,\n );\n\n const entries = sideData.entriesSorted;\n this.logDebug(\n action.context,\n 'First entry for Bind Join: ',\n () => ({ entry: entries[0].operation, metadata: entries[0].metadata }),\n );\n\n // Close the non-smallest streams\n for (const [ i, element ] of entries.entries()) {\n if (i !== 0) {\n element.output.bindingsStream.close();\n }\n }\n\n // Take the stream with the lowest cardinality\n const smallestStream: IQueryOperationResultBindings = entries[0].output;\n const remainingEntries = [ ...entries ];\n remainingEntries.splice(0, 1);\n\n // Bind the remaining patterns for each binding in the stream\n const subContext = action.context\n .set(KeysQueryOperation.joinLeftMetadata, entries[0].metadata)\n .set(KeysQueryOperation.joinRightMetadatas, remainingEntries.map(entry => entry.metadata));\n const bindingsStream: BindingsStream = ActorRdfJoinMultiBind.createBindStream(\n this.bindOrder,\n smallestStream.bindingsStream,\n remainingEntries.map(entry => entry.operation),\n async(operations: Algebra.Operation[], operationBindings: Bindings) => {\n // Send the materialized patterns to the mediator for recursive join evaluation.\n const operation = operations.length === 1 ?\n operations[0] :\n algebraFactory.createJoin(operations);\n const output = getSafeBindings(await this.mediatorQueryOperation.mediate(\n { operation, context: subContext?.set(KeysQueryOperation.joinBindings, operationBindings) },\n ));\n return output.bindingsStream;\n },\n false,\n algebraFactory,\n bindingsFactory,\n );\n\n return {\n result: {\n type: 'bindings',\n bindingsStream,\n metadata: () => this.constructResultMetadata(entries, entries.map(entry => entry.metadata), action.context),\n },\n physicalPlanMetadata: {\n bindIndex: sideData.entriesUnsorted.indexOf(entries[0]),\n bindOperation: entries[0].operation,\n bindOperationCardinality: entries[0].metadata.cardinality,\n bindOrder: this.bindOrder,\n },\n };\n }\n\n public canBindWithOperation(operation: Algebra.Operation): boolean {\n let valid = true;\n Util.recurseOperation(operation, {\n [Algebra.types.EXTEND](): boolean {\n valid = false;\n return false;\n },\n [Algebra.types.GROUP](): boolean {\n valid = false;\n return false;\n },\n });\n\n return valid;\n }\n\n public async getJoinCoefficients(\n action: IActionRdfJoin,\n sideData: IActorRdfJoinTestSideData,\n ): Promise<TestResult<IMediatorTypeJoinCoefficients, IActorRdfJoinMultiBindTestSideData>> {\n let { metadatas } = sideData;\n\n // Order the entries so we can pick the first one (usually the one with the lowest cardinality)\n const entriesUnsorted = action.entries\n .map((entry, i) => ({ ...entry, metadata: metadatas[i] }));\n const entriesTest = await ActorRdfJoin\n .sortJoinEntries(this.mediatorJoinEntriesSort, entriesUnsorted, action.context);\n if (entriesTest.isFailed()) {\n return entriesTest;\n }\n const entriesSorted = entriesTest.get();\n metadatas = entriesSorted.map(entry => entry.metadata);\n\n const requestInitialTimes = ActorRdfJoin.getRequestInitialTimes(metadatas);\n const requestItemTimes = ActorRdfJoin.getRequestItemTimes(metadatas);\n\n // Determine first stream and remaining ones\n const remainingEntries = [ ...entriesSorted ];\n const remainingRequestInitialTimes = [ ...requestInitialTimes ];\n const remainingRequestItemTimes = [ ...requestItemTimes ];\n remainingEntries.splice(0, 1);\n remainingRequestInitialTimes.splice(0, 1);\n remainingRequestItemTimes.splice(0, 1);\n\n // Reject binding on some operation types\n if (remainingEntries\n .some(entry => !this.canBindWithOperation(entry.operation))) {\n return failTest(`Actor ${this.name} can not bind on Extend and Group operations`);\n }\n\n // Reject binding on modified operations, since using the output directly would be significantly more efficient.\n if (remainingEntries.some(entry => entry.operationModified)) {\n return failTest(`Actor ${this.name} can not be used over remaining entries with modified operations`);\n }\n\n // Only run this actor if the smallest stream is significantly smaller than the largest stream.\n // We must use Math.max, because the last metadata is not necessarily the biggest, but it's the least preferred.\n if (metadatas[0].cardinality.value * this.minMaxCardinalityRatio >\n Math.max(...metadatas.map(metadata => metadata.cardinality.value))) {\n return failTest(`Actor ${this.name} can only run if the smallest stream is much smaller than largest stream`);\n }\n\n // Determine selectivities of smallest entry with all other entries\n const selectivities = await Promise.all(remainingEntries\n .map(async entry => (await this.mediatorJoinSelectivity.mediate({\n entries: [ entriesSorted[0], entry ],\n context: action.context,\n })).selectivity * this.selectivityModifier));\n\n // Determine coefficients for remaining entries\n const cardinalityRemaining = remainingEntries\n .map((entry, i) => entry.metadata.cardinality.value * selectivities[i])\n .reduce((sum, element) => sum + element, 0);\n const receiveInitialCostRemaining = remainingRequestInitialTimes\n .reduce((sum, element) => sum + element, 0);\n const receiveItemCostRemaining = remainingRequestItemTimes\n .reduce((sum, element) => sum + element, 0);\n\n return passTestWithSideData({\n iterations: metadatas[0].cardinality.value * cardinalityRemaining,\n persistedItems: 0,\n blockingItems: 0,\n requestTime: requestInitialTimes[0] +\n metadatas[0].cardinality.value * (\n requestItemTimes[0] +\n receiveInitialCostRemaining +\n cardinalityRemaining * receiveItemCostRemaining\n ),\n }, { ...sideData, entriesUnsorted, entriesSorted });\n }\n}\n\nexport interface IActorRdfJoinMultiBindArgs extends IActorRdfJoinArgs<IActorRdfJoinMultiBindTestSideData> {\n /**\n * The order in which elements should be bound\n * @default {depth-first}\n */\n bindOrder: BindOrder;\n /**\n * Multiplier for selectivity values\n * @range {double}\n * @default {0.0001}\n */\n selectivityModifier: number;\n /**\n * The number of times the smallest cardinality should fit in the maximum cardinality.\n * @range {double}\n * @default {60}\n */\n minMaxCardinalityRatio: number;\n /**\n * The join entries sort mediator\n */\n mediatorJoinEntriesSort: MediatorRdfJoinEntriesSort;\n /**\n * The query operation mediator\n */\n mediatorQueryOperation: MediatorQueryOperation;\n /**\n * A mediator for creating binding context merge handlers\n */\n mediatorMergeBindingsContext: MediatorMergeBindingsContext;\n}\n\nexport type BindOrder = 'depth-first' | 'breadth-first';\n\nexport interface IActorRdfJoinMultiBindTestSideData extends IActorRdfJoinTestSideData {\n entriesUnsorted: IJoinEntryWithMetadata[];\n entriesSorted: IJoinEntryWithMetadata[];\n}\n"]}
package/package.json CHANGED
@@ -1,9 +1,13 @@
1
1
  {
2
2
  "name": "@comunica/actor-rdf-join-inner-multi-bind",
3
- "version": "3.2.2",
3
+ "version": "3.2.4-alpha.47.0",
4
4
  "description": "A multi-bind rdf-join actor",
5
5
  "lsd:module": true,
6
6
  "license": "MIT",
7
+ "funding": {
8
+ "type": "opencollective",
9
+ "url": "https://opencollective.com/comunica-association"
10
+ },
7
11
  "homepage": "https://comunica.dev/",
8
12
  "repository": {
9
13
  "type": "git",
@@ -37,16 +41,18 @@
37
41
  "build:components": "componentsjs-generator"
38
42
  },
39
43
  "dependencies": {
40
- "@comunica/bindings-factory": "^3.2.1",
41
- "@comunica/bus-merge-bindings-context": "^3.2.1",
42
- "@comunica/bus-query-operation": "^3.2.2",
43
- "@comunica/bus-rdf-join": "^3.2.1",
44
- "@comunica/bus-rdf-join-entries-sort": "^3.2.1",
45
- "@comunica/context-entries": "^3.2.1",
46
- "@comunica/mediatortype-join-coefficients": "^3.2.1",
47
- "@comunica/types": "^3.2.1",
44
+ "@comunica/bus-merge-bindings-context": "3.2.4-alpha.47.0",
45
+ "@comunica/bus-query-operation": "3.2.4-alpha.47.0",
46
+ "@comunica/bus-rdf-join": "3.2.4-alpha.47.0",
47
+ "@comunica/bus-rdf-join-entries-sort": "3.2.4-alpha.47.0",
48
+ "@comunica/context-entries": "3.2.4-alpha.47.0",
49
+ "@comunica/core": "3.2.4-alpha.47.0",
50
+ "@comunica/mediatortype-join-coefficients": "3.2.4-alpha.47.0",
51
+ "@comunica/types": "3.2.4-alpha.47.0",
52
+ "@comunica/utils-bindings-factory": "3.2.4-alpha.47.0",
53
+ "@comunica/utils-query-operation": "3.2.4-alpha.47.0",
48
54
  "asynciterator": "^3.9.0",
49
- "sparqlalgebrajs": "^4.3.7"
55
+ "sparqlalgebrajs": "^4.3.8"
50
56
  },
51
- "gitHead": "fbcc3a81f87738633ddf69ede5ca504236f7edd9"
57
+ "gitHead": "85bd4c5cf07dfc293ebbc3a1416b70e2db8bfc48"
52
58
  }