@comunica/actor-query-source-identify-hypermedia 4.4.2-alpha.49.0 → 4.5.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.
- package/README.md +11 -5
- package/components/ActorQuerySourceIdentifyHypermedia.jsonld +110 -8
- package/components/QuerySourceHypermedia.jsonld +115 -18
- package/components/components.jsonld +0 -0
- package/components/context.jsonld +84 -12
- package/lib/ActorQuerySourceIdentifyHypermedia.d.ts +40 -4
- package/lib/ActorQuerySourceIdentifyHypermedia.js +8 -5
- package/lib/ActorQuerySourceIdentifyHypermedia.js.map +1 -1
- package/lib/LinkedRdfSourcesAsyncRdfIterator.d.ts +6 -4
- package/lib/LinkedRdfSourcesAsyncRdfIterator.js +6 -5
- package/lib/LinkedRdfSourcesAsyncRdfIterator.js.map +1 -1
- package/lib/MediatedLinkedRdfSourcesAsyncRdfIterator.d.ts +17 -5
- package/lib/MediatedLinkedRdfSourcesAsyncRdfIterator.js +92 -6
- package/lib/MediatedLinkedRdfSourcesAsyncRdfIterator.js.map +1 -1
- package/lib/QuerySourceHypermedia.d.ts +22 -10
- package/lib/QuerySourceHypermedia.js +135 -22
- package/lib/QuerySourceHypermedia.js.map +1 -1
- package/lib/StreamingStoreMetadata.d.ts +31 -0
- package/lib/StreamingStoreMetadata.js +110 -0
- package/lib/StreamingStoreMetadata.js.map +1 -0
- package/lib/index.d.ts +0 -0
- package/lib/index.js +0 -0
- package/lib/index.js.map +0 -0
- package/package.json +23 -16
|
@@ -1,18 +1,24 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { MediatorDereferenceRdf } from '@comunica/bus-dereference-rdf';
|
|
2
|
+
import type { MediatorQuerySourceIdentifyHypermedia } from '@comunica/bus-query-source-identify-hypermedia';
|
|
3
|
+
import type { MediatorRdfMetadata } from '@comunica/bus-rdf-metadata';
|
|
2
4
|
import type { MediatorRdfMetadataAccumulate } from '@comunica/bus-rdf-metadata-accumulate';
|
|
5
|
+
import type { MediatorRdfMetadataExtract } from '@comunica/bus-rdf-metadata-extract';
|
|
3
6
|
import type { MediatorRdfResolveHypermediaLinks } from '@comunica/bus-rdf-resolve-hypermedia-links';
|
|
4
7
|
import type { MediatorRdfResolveHypermediaLinksQueue } from '@comunica/bus-rdf-resolve-hypermedia-links-queue';
|
|
5
|
-
import type { BindingsStream, ComunicaDataFactory, FragmentSelectorShape, IActionContext, IQueryBindingsOptions, IQuerySource, ILink } from '@comunica/types';
|
|
6
|
-
import type { Algebra } from '@comunica/utils-algebra';
|
|
8
|
+
import type { BindingsStream, ComunicaDataFactory, FragmentSelectorShape, IActionContext, IAggregatedStore, IQueryBindingsOptions, IQuerySource, ILink } from '@comunica/types';
|
|
7
9
|
import type { BindingsFactory } from '@comunica/utils-bindings-factory';
|
|
8
10
|
import type * as RDF from '@rdfjs/types';
|
|
9
11
|
import type { AsyncIterator } from 'asynciterator';
|
|
10
12
|
import { LRUCache } from 'lru-cache';
|
|
13
|
+
import type { Algebra } from 'sparqlalgebrajs';
|
|
11
14
|
import type { ISourceState } from './LinkedRdfSourcesAsyncRdfIterator';
|
|
12
15
|
export declare class QuerySourceHypermedia implements IQuerySource {
|
|
13
16
|
readonly referenceValue: string;
|
|
14
|
-
readonly
|
|
17
|
+
readonly firstUrl: string;
|
|
18
|
+
readonly forceSourceType?: string;
|
|
19
|
+
readonly aggregateStore: boolean;
|
|
15
20
|
readonly mediators: IMediatorArgs;
|
|
21
|
+
readonly logWarning: (warningMessage: string) => void;
|
|
16
22
|
readonly dataFactory: ComunicaDataFactory;
|
|
17
23
|
readonly bindingsFactory: BindingsFactory;
|
|
18
24
|
/**
|
|
@@ -21,33 +27,39 @@ export declare class QuerySourceHypermedia implements IQuerySource {
|
|
|
21
27
|
sourcesState: LRUCache<string, Promise<ISourceState>>;
|
|
22
28
|
private readonly cacheSize;
|
|
23
29
|
private readonly maxIterators;
|
|
24
|
-
|
|
30
|
+
private readonly emitPartialCardinalities;
|
|
31
|
+
constructor(cacheSize: number, firstUrl: string, forceSourceType: string | undefined, maxIterators: number, aggregateStore: boolean, emitPartialCardinalities: boolean, mediators: IMediatorArgs, logWarning: (warningMessage: string) => void, dataFactory: ComunicaDataFactory, bindingsFactory: BindingsFactory);
|
|
25
32
|
getSelectorShape(context: IActionContext): Promise<FragmentSelectorShape>;
|
|
26
|
-
getFilterFactor(context: IActionContext): Promise<number>;
|
|
27
33
|
queryBindings(operation: Algebra.Operation, context: IActionContext, options?: IQueryBindingsOptions): BindingsStream;
|
|
28
34
|
queryQuads(operation: Algebra.Operation, context: IActionContext): AsyncIterator<RDF.Quad>;
|
|
29
35
|
queryBoolean(operation: Algebra.Ask, context: IActionContext): Promise<boolean>;
|
|
30
|
-
queryVoid(operation: Algebra.
|
|
36
|
+
queryVoid(operation: Algebra.Update, context: IActionContext): Promise<void>;
|
|
31
37
|
/**
|
|
32
38
|
* Resolve a source for the given URL.
|
|
33
39
|
* @param link A source link.
|
|
34
40
|
* @param handledDatasets A hash of dataset identifiers that have already been handled.
|
|
35
41
|
* @param context The action context.
|
|
42
|
+
* @param aggregatedStore An optional aggregated store.
|
|
36
43
|
*/
|
|
37
|
-
getSource(link: ILink, handledDatasets: Record<string, boolean>, context: IActionContext): Promise<ISourceState>;
|
|
44
|
+
getSource(link: ILink, handledDatasets: Record<string, boolean>, context: IActionContext, aggregatedStore: IAggregatedStore | undefined): Promise<ISourceState>;
|
|
38
45
|
/**
|
|
39
46
|
* Resolve a source for the given URL.
|
|
40
47
|
* This will first try to retrieve the source from cache.
|
|
41
48
|
* @param link A source ILink.
|
|
42
49
|
* @param handledDatasets A hash of dataset identifiers that have already been handled.
|
|
43
50
|
* @param context The action context.
|
|
51
|
+
* @param aggregatedStore An optional aggregated store.
|
|
44
52
|
*/
|
|
45
|
-
protected getSourceCached(link: ILink, handledDatasets: Record<string, boolean>, context: IActionContext): Promise<ISourceState>;
|
|
53
|
+
protected getSourceCached(link: ILink, handledDatasets: Record<string, boolean>, context: IActionContext, aggregatedStore: IAggregatedStore | undefined): Promise<ISourceState>;
|
|
54
|
+
getAggregateStore(context: IActionContext): IAggregatedStore | undefined;
|
|
46
55
|
toString(): string;
|
|
47
56
|
}
|
|
48
57
|
export interface IMediatorArgs {
|
|
58
|
+
mediatorDereferenceRdf: MediatorDereferenceRdf;
|
|
59
|
+
mediatorMetadata: MediatorRdfMetadata;
|
|
60
|
+
mediatorMetadataExtract: MediatorRdfMetadataExtract;
|
|
49
61
|
mediatorMetadataAccumulate: MediatorRdfMetadataAccumulate;
|
|
50
|
-
|
|
62
|
+
mediatorQuerySourceIdentifyHypermedia: MediatorQuerySourceIdentifyHypermedia;
|
|
51
63
|
mediatorRdfResolveHypermediaLinks: MediatorRdfResolveHypermediaLinks;
|
|
52
64
|
mediatorRdfResolveHypermediaLinksQueue: MediatorRdfResolveHypermediaLinksQueue;
|
|
53
65
|
}
|
|
@@ -1,49 +1,69 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.QuerySourceHypermedia = void 0;
|
|
4
|
+
const actor_query_source_identify_rdfjs_1 = require("@comunica/actor-query-source-identify-rdfjs");
|
|
5
|
+
const context_entries_1 = require("@comunica/context-entries");
|
|
4
6
|
const asynciterator_1 = require("asynciterator");
|
|
5
7
|
const lru_cache_1 = require("lru-cache");
|
|
8
|
+
const readable_stream_1 = require("readable-stream");
|
|
9
|
+
const sparqlalgebrajs_1 = require("sparqlalgebrajs");
|
|
6
10
|
const MediatedLinkedRdfSourcesAsyncRdfIterator_1 = require("./MediatedLinkedRdfSourcesAsyncRdfIterator");
|
|
11
|
+
const StreamingStoreMetadata_1 = require("./StreamingStoreMetadata");
|
|
7
12
|
class QuerySourceHypermedia {
|
|
8
|
-
constructor(cacheSize, firstUrl, maxIterators, mediators, dataFactory, bindingsFactory) {
|
|
9
|
-
this.referenceValue = firstUrl
|
|
13
|
+
constructor(cacheSize, firstUrl, forceSourceType, maxIterators, aggregateStore, emitPartialCardinalities, mediators, logWarning, dataFactory, bindingsFactory) {
|
|
14
|
+
this.referenceValue = firstUrl;
|
|
10
15
|
this.cacheSize = cacheSize;
|
|
11
|
-
this.
|
|
16
|
+
this.firstUrl = firstUrl;
|
|
17
|
+
this.forceSourceType = forceSourceType;
|
|
12
18
|
this.maxIterators = maxIterators;
|
|
13
19
|
this.mediators = mediators;
|
|
20
|
+
this.aggregateStore = aggregateStore;
|
|
21
|
+
this.emitPartialCardinalities = emitPartialCardinalities;
|
|
22
|
+
this.logWarning = logWarning;
|
|
14
23
|
this.dataFactory = dataFactory;
|
|
15
24
|
this.bindingsFactory = bindingsFactory;
|
|
16
25
|
this.sourcesState = new lru_cache_1.LRUCache({ max: this.cacheSize });
|
|
17
26
|
}
|
|
18
27
|
async getSelectorShape(context) {
|
|
19
|
-
const source = await this.getSourceCached(this.
|
|
28
|
+
const source = await this.getSourceCached({ url: this.firstUrl }, {}, context, this.getAggregateStore(context));
|
|
20
29
|
return source.source.getSelectorShape(context);
|
|
21
30
|
}
|
|
22
|
-
async getFilterFactor(context) {
|
|
23
|
-
const source = await this.getSourceCached(this.firstLink, {}, context);
|
|
24
|
-
return source.source.getFilterFactor(context);
|
|
25
|
-
}
|
|
26
31
|
queryBindings(operation, context, options) {
|
|
32
|
+
// Optimized match with aggregated store if enabled and started.
|
|
33
|
+
const aggregatedStore = this.getAggregateStore(context);
|
|
34
|
+
if (aggregatedStore && operation.type === 'pattern' && aggregatedStore.started) {
|
|
35
|
+
return new actor_query_source_identify_rdfjs_1.QuerySourceRdfJs(aggregatedStore, context.getSafe(context_entries_1.KeysInitQuery.dataFactory), this.bindingsFactory).queryBindings(operation, context);
|
|
36
|
+
}
|
|
27
37
|
// Initialize the sources state on first call
|
|
28
38
|
if (this.sourcesState.size === 0) {
|
|
29
|
-
this.getSourceCached(this.
|
|
39
|
+
this.getSourceCached({ url: this.firstUrl }, {}, context, aggregatedStore)
|
|
30
40
|
.catch(error => it.destroy(error));
|
|
31
41
|
}
|
|
32
|
-
const
|
|
42
|
+
const dataFactory = context.getSafe(context_entries_1.KeysInitQuery.dataFactory);
|
|
43
|
+
const algebraFactory = new sparqlalgebrajs_1.Factory(dataFactory);
|
|
44
|
+
const it = new MediatedLinkedRdfSourcesAsyncRdfIterator_1.MediatedLinkedRdfSourcesAsyncRdfIterator(this.cacheSize, operation, options, context, this.forceSourceType, this.firstUrl, this.maxIterators, (link, handledDatasets) => this.getSourceCached(link, handledDatasets, context, aggregatedStore), aggregatedStore, this.mediators.mediatorMetadataAccumulate, this.mediators.mediatorRdfResolveHypermediaLinks, this.mediators.mediatorRdfResolveHypermediaLinksQueue, dataFactory, algebraFactory);
|
|
45
|
+
if (aggregatedStore) {
|
|
46
|
+
aggregatedStore.started = true;
|
|
47
|
+
// Kickstart this iterator when derived iterators are created from the aggregatedStore,
|
|
48
|
+
// otherwise the traversal process will not start if this iterator is not the first one to be consumed.
|
|
49
|
+
const listener = () => it.kickstart();
|
|
50
|
+
aggregatedStore.addIteratorCreatedListener(listener);
|
|
51
|
+
it.on('end', () => aggregatedStore.removeIteratorCreatedListener(listener));
|
|
52
|
+
}
|
|
33
53
|
return it;
|
|
34
54
|
}
|
|
35
55
|
queryQuads(operation, context) {
|
|
36
56
|
return new asynciterator_1.TransformIterator(async () => {
|
|
37
|
-
const source = await this.getSourceCached(this.
|
|
57
|
+
const source = await this.getSourceCached({ url: this.firstUrl }, {}, context, this.getAggregateStore(context));
|
|
38
58
|
return source.source.queryQuads(operation, context);
|
|
39
59
|
});
|
|
40
60
|
}
|
|
41
61
|
async queryBoolean(operation, context) {
|
|
42
|
-
const source = await this.getSourceCached(this.
|
|
62
|
+
const source = await this.getSourceCached({ url: this.firstUrl }, {}, context, this.getAggregateStore(context));
|
|
43
63
|
return await source.source.queryBoolean(operation, context);
|
|
44
64
|
}
|
|
45
65
|
async queryVoid(operation, context) {
|
|
46
|
-
const source = await this.getSourceCached(this.
|
|
66
|
+
const source = await this.getSourceCached({ url: this.firstUrl }, {}, context, this.getAggregateStore(context));
|
|
47
67
|
return await source.source.queryVoid(operation, context);
|
|
48
68
|
}
|
|
49
69
|
/**
|
|
@@ -51,14 +71,84 @@ class QuerySourceHypermedia {
|
|
|
51
71
|
* @param link A source link.
|
|
52
72
|
* @param handledDatasets A hash of dataset identifiers that have already been handled.
|
|
53
73
|
* @param context The action context.
|
|
74
|
+
* @param aggregatedStore An optional aggregated store.
|
|
54
75
|
*/
|
|
55
|
-
async getSource(link, handledDatasets, context) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
76
|
+
async getSource(link, handledDatasets, context, aggregatedStore) {
|
|
77
|
+
// Include context entries from link
|
|
78
|
+
if (link.context) {
|
|
79
|
+
context = context.merge(link.context);
|
|
80
|
+
}
|
|
81
|
+
// Get the RDF representation of the given document
|
|
82
|
+
let url = link.url;
|
|
83
|
+
let quads;
|
|
84
|
+
let metadata;
|
|
85
|
+
if (this.forceSourceType === 'sparql' && context.get(context_entries_1.KeysQueryOperation.querySources)?.length === 1) {
|
|
86
|
+
// Skip metadata extraction if we're querying over just a single SPARQL endpoint.
|
|
87
|
+
quads = new readable_stream_1.Readable();
|
|
88
|
+
quads.read = () => null;
|
|
89
|
+
({ metadata } = await this.mediators.mediatorMetadataAccumulate.mediate({ context, mode: 'initialize' }));
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
try {
|
|
93
|
+
const dereferenceRdfOutput = await this.mediators.mediatorDereferenceRdf
|
|
94
|
+
.mediate({ context, url });
|
|
95
|
+
url = dereferenceRdfOutput.url;
|
|
96
|
+
// Determine the metadata
|
|
97
|
+
const rdfMetadataOutput = await this.mediators.mediatorMetadata.mediate({ context, url, quads: dereferenceRdfOutput.data, triples: dereferenceRdfOutput.metadata?.triples });
|
|
98
|
+
rdfMetadataOutput.data.on('error', () => {
|
|
99
|
+
// Silence errors in the data stream,
|
|
100
|
+
// as they will be emitted again in the metadata stream,
|
|
101
|
+
// and will result in a promise rejection anyways.
|
|
102
|
+
// If we don't do this, we end up with an unhandled error message
|
|
103
|
+
});
|
|
104
|
+
metadata = (await this.mediators.mediatorMetadataExtract.mediate({
|
|
105
|
+
context,
|
|
106
|
+
url,
|
|
107
|
+
// The problem appears to be conflicting metadata keys here
|
|
108
|
+
metadata: rdfMetadataOutput.metadata,
|
|
109
|
+
headers: dereferenceRdfOutput.headers,
|
|
110
|
+
requestTime: dereferenceRdfOutput.requestTime,
|
|
111
|
+
})).metadata;
|
|
112
|
+
quads = rdfMetadataOutput.data;
|
|
113
|
+
// Optionally filter the resulting data
|
|
114
|
+
if (link.transform) {
|
|
115
|
+
quads = await link.transform(quads);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
// Make sure that dereference errors are only emitted once an actor really needs the read quads
|
|
120
|
+
// This allows SPARQL endpoints that error on service description fetching to still be source-forcible
|
|
121
|
+
quads = new readable_stream_1.Readable();
|
|
122
|
+
quads.read = () => {
|
|
123
|
+
setTimeout(() => quads.emit('error', error));
|
|
124
|
+
return null;
|
|
125
|
+
};
|
|
126
|
+
({ metadata } = await this.mediators.mediatorMetadataAccumulate.mediate({ context, mode: 'initialize' }));
|
|
127
|
+
// Log as warning, because the quads above may not always be consumed (e.g. for SPARQL endpoints),
|
|
128
|
+
// so the user would not be notified of something going wrong otherwise.
|
|
129
|
+
this.logWarning(`Metadata extraction for ${url} failed: ${error.message}`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// Aggregate all discovered quads into a store.
|
|
133
|
+
aggregatedStore?.setBaseMetadata(metadata, false);
|
|
134
|
+
aggregatedStore?.containedSources.add(link.url);
|
|
135
|
+
aggregatedStore?.import(quads);
|
|
136
|
+
// Determine the source
|
|
137
|
+
const { source, dataset } = await this.mediators.mediatorQuerySourceIdentifyHypermedia.mediate({
|
|
59
138
|
context,
|
|
139
|
+
forceSourceType: link.url === this.firstUrl ? this.forceSourceType : undefined,
|
|
140
|
+
handledDatasets,
|
|
141
|
+
metadata,
|
|
142
|
+
quads,
|
|
143
|
+
url,
|
|
60
144
|
});
|
|
61
|
-
|
|
145
|
+
if (dataset) {
|
|
146
|
+
// Mark the dataset as applied
|
|
147
|
+
// This is needed to make sure that things like QPF search forms are only applied once,
|
|
148
|
+
// and next page links are followed after that.
|
|
149
|
+
handledDatasets[dataset] = true;
|
|
150
|
+
}
|
|
151
|
+
return { link, source, metadata: metadata, handledDatasets };
|
|
62
152
|
}
|
|
63
153
|
/**
|
|
64
154
|
* Resolve a source for the given URL.
|
|
@@ -66,18 +156,41 @@ class QuerySourceHypermedia {
|
|
|
66
156
|
* @param link A source ILink.
|
|
67
157
|
* @param handledDatasets A hash of dataset identifiers that have already been handled.
|
|
68
158
|
* @param context The action context.
|
|
159
|
+
* @param aggregatedStore An optional aggregated store.
|
|
69
160
|
*/
|
|
70
|
-
getSourceCached(link, handledDatasets, context) {
|
|
161
|
+
getSourceCached(link, handledDatasets, context, aggregatedStore) {
|
|
71
162
|
let source = this.sourcesState.get(link.url);
|
|
72
163
|
if (source) {
|
|
73
164
|
return source;
|
|
74
165
|
}
|
|
75
|
-
source = this.getSource(link, handledDatasets, context);
|
|
76
|
-
|
|
166
|
+
source = this.getSource(link, handledDatasets, context, aggregatedStore);
|
|
167
|
+
if (link.url === this.firstUrl || aggregatedStore === undefined) {
|
|
168
|
+
this.sourcesState.set(link.url, source);
|
|
169
|
+
}
|
|
77
170
|
return source;
|
|
78
171
|
}
|
|
172
|
+
getAggregateStore(context) {
|
|
173
|
+
let aggregatedStore;
|
|
174
|
+
if (this.aggregateStore) {
|
|
175
|
+
const aggregatedStores = context
|
|
176
|
+
.get(context_entries_1.KeysQuerySourceIdentify.hypermediaSourcesAggregatedStores);
|
|
177
|
+
if (aggregatedStores) {
|
|
178
|
+
aggregatedStore = aggregatedStores.get(this.firstUrl);
|
|
179
|
+
if (!aggregatedStore) {
|
|
180
|
+
aggregatedStore = new StreamingStoreMetadata_1.StreamingStoreMetadata(undefined, async (accumulatedMetadata, appendingMetadata) => (await this.mediators.mediatorMetadataAccumulate.mediate({
|
|
181
|
+
mode: 'append',
|
|
182
|
+
accumulatedMetadata,
|
|
183
|
+
appendingMetadata,
|
|
184
|
+
context,
|
|
185
|
+
})).metadata, this.emitPartialCardinalities);
|
|
186
|
+
aggregatedStores.set(this.firstUrl, aggregatedStore);
|
|
187
|
+
}
|
|
188
|
+
return aggregatedStore;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
79
192
|
toString() {
|
|
80
|
-
return `QuerySourceHypermedia(${this.
|
|
193
|
+
return `QuerySourceHypermedia(${this.firstUrl})`;
|
|
81
194
|
}
|
|
82
195
|
}
|
|
83
196
|
exports.QuerySourceHypermedia = QuerySourceHypermedia;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QuerySourceHypermedia.js","sourceRoot":"","sources":["QuerySourceHypermedia.ts"],"names":[],"mappings":"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","sourcesContent":["import type { MediatorQuerySourceDereferenceLink } from '@comunica/bus-query-source-dereference-link';\nimport type { MediatorRdfMetadataAccumulate } from '@comunica/bus-rdf-metadata-accumulate';\nimport type { MediatorRdfResolveHypermediaLinks } from '@comunica/bus-rdf-resolve-hypermedia-links';\nimport type { MediatorRdfResolveHypermediaLinksQueue } from '@comunica/bus-rdf-resolve-hypermedia-links-queue';\nimport type {\n BindingsStream,\n ComunicaDataFactory,\n FragmentSelectorShape,\n IActionContext,\n IQueryBindingsOptions,\n IQuerySource,\n ILink,\n} from '@comunica/types';\nimport type { Algebra } from '@comunica/utils-algebra';\nimport type { BindingsFactory } from '@comunica/utils-bindings-factory';\nimport type * as RDF from '@rdfjs/types';\nimport type { AsyncIterator } from 'asynciterator';\nimport { TransformIterator } from 'asynciterator';\nimport { LRUCache } from 'lru-cache';\nimport type { ISourceState } from './LinkedRdfSourcesAsyncRdfIterator';\nimport { MediatedLinkedRdfSourcesAsyncRdfIterator } from './MediatedLinkedRdfSourcesAsyncRdfIterator';\n\nexport class QuerySourceHypermedia implements IQuerySource {\n public readonly referenceValue: string;\n public readonly firstLink: ILink;\n public readonly mediators: IMediatorArgs;\n public readonly dataFactory: ComunicaDataFactory;\n public readonly bindingsFactory: BindingsFactory;\n\n /**\n * A cache for source URLs to source states.\n */\n public sourcesState: LRUCache<string, Promise<ISourceState>>;\n\n private readonly cacheSize: number;\n private readonly maxIterators: number;\n\n public constructor(\n cacheSize: number,\n firstUrl: ILink,\n maxIterators: number,\n mediators: IMediatorArgs,\n dataFactory: ComunicaDataFactory,\n bindingsFactory: BindingsFactory,\n ) {\n this.referenceValue = firstUrl.url;\n this.cacheSize = cacheSize;\n this.firstLink = firstUrl;\n this.maxIterators = maxIterators;\n this.mediators = mediators;\n this.dataFactory = dataFactory;\n this.bindingsFactory = bindingsFactory;\n this.sourcesState = new LRUCache<string, Promise<ISourceState>>({ max: this.cacheSize });\n }\n\n public async getSelectorShape(context: IActionContext): Promise<FragmentSelectorShape> {\n const source = await this.getSourceCached(this.firstLink, {}, context);\n return source.source.getSelectorShape(context);\n }\n\n public async getFilterFactor(context: IActionContext): Promise<number> {\n const source = await this.getSourceCached(this.firstLink, {}, context);\n return source.source.getFilterFactor(context);\n }\n\n public queryBindings(\n operation: Algebra.Operation,\n context: IActionContext,\n options?: IQueryBindingsOptions,\n ): BindingsStream {\n // Initialize the sources state on first call\n if (this.sourcesState.size === 0) {\n this.getSourceCached(this.firstLink, {}, context)\n .catch(error => it.destroy(error));\n }\n\n const it: MediatedLinkedRdfSourcesAsyncRdfIterator = new MediatedLinkedRdfSourcesAsyncRdfIterator(\n operation,\n options,\n context,\n this.firstLink,\n this.maxIterators,\n (link, handledDatasets) => this.getSourceCached(link, handledDatasets, context),\n this.mediators.mediatorMetadataAccumulate,\n this.mediators.mediatorRdfResolveHypermediaLinks,\n this.mediators.mediatorRdfResolveHypermediaLinksQueue,\n );\n\n return it;\n }\n\n public queryQuads(operation: Algebra.Operation, context: IActionContext): AsyncIterator<RDF.Quad> {\n return new TransformIterator(async() => {\n const source = await this.getSourceCached(this.firstLink, {}, context);\n return source.source.queryQuads(operation, context);\n });\n }\n\n public async queryBoolean(operation: Algebra.Ask, context: IActionContext): Promise<boolean> {\n const source = await this.getSourceCached(this.firstLink, {}, context);\n return await source.source.queryBoolean(operation, context);\n }\n\n public async queryVoid(operation: Algebra.Operation, context: IActionContext): Promise<void> {\n const source = await this.getSourceCached(this.firstLink, {}, context);\n return await source.source.queryVoid(operation, context);\n }\n\n /**\n * Resolve a source for the given URL.\n * @param link A source link.\n * @param handledDatasets A hash of dataset identifiers that have already been handled.\n * @param context The action context.\n */\n public async getSource(\n link: ILink,\n handledDatasets: Record<string, boolean>,\n context: IActionContext,\n ): Promise<ISourceState> {\n const { source, metadata } = await this.mediators.mediatorQuerySourceDereferenceLink.mediate({\n link,\n handledDatasets,\n context,\n });\n\n return { link, source, metadata, handledDatasets };\n }\n\n /**\n * Resolve a source for the given URL.\n * This will first try to retrieve the source from cache.\n * @param link A source ILink.\n * @param handledDatasets A hash of dataset identifiers that have already been handled.\n * @param context The action context.\n */\n protected getSourceCached(\n link: ILink,\n handledDatasets: Record<string, boolean>,\n context: IActionContext,\n ): Promise<ISourceState> {\n let source = this.sourcesState.get(link.url);\n if (source) {\n return source;\n }\n source = this.getSource(link, handledDatasets, context);\n this.sourcesState.set(link.url, source);\n return source;\n }\n\n public toString(): string {\n return `QuerySourceHypermedia(${this.firstLink.url})`;\n }\n}\n\nexport interface IMediatorArgs {\n mediatorMetadataAccumulate: MediatorRdfMetadataAccumulate;\n mediatorQuerySourceDereferenceLink: MediatorQuerySourceDereferenceLink;\n mediatorRdfResolveHypermediaLinks: MediatorRdfResolveHypermediaLinks;\n mediatorRdfResolveHypermediaLinksQueue: MediatorRdfResolveHypermediaLinksQueue;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"QuerySourceHypermedia.js","sourceRoot":"","sources":["QuerySourceHypermedia.ts"],"names":[],"mappings":"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","sourcesContent":["import { QuerySourceRdfJs } from '@comunica/actor-query-source-identify-rdfjs';\nimport type { IActorDereferenceRdfOutput, MediatorDereferenceRdf } from '@comunica/bus-dereference-rdf';\nimport type { MediatorQuerySourceIdentifyHypermedia } from '@comunica/bus-query-source-identify-hypermedia';\nimport type { IActorRdfMetadataOutput, MediatorRdfMetadata } from '@comunica/bus-rdf-metadata';\nimport type { MediatorRdfMetadataAccumulate } from '@comunica/bus-rdf-metadata-accumulate';\nimport type { MediatorRdfMetadataExtract } from '@comunica/bus-rdf-metadata-extract';\nimport type { MediatorRdfResolveHypermediaLinks } from '@comunica/bus-rdf-resolve-hypermedia-links';\nimport type { MediatorRdfResolveHypermediaLinksQueue } from '@comunica/bus-rdf-resolve-hypermedia-links-queue';\nimport { KeysInitQuery, KeysQueryOperation, KeysQuerySourceIdentify } from '@comunica/context-entries';\nimport type {\n BindingsStream,\n ComunicaDataFactory,\n FragmentSelectorShape,\n IActionContext,\n IAggregatedStore,\n IQueryBindingsOptions,\n IQuerySource,\n MetadataBindings,\n ILink,\n} from '@comunica/types';\nimport type { BindingsFactory } from '@comunica/utils-bindings-factory';\nimport type * as RDF from '@rdfjs/types';\nimport type { AsyncIterator } from 'asynciterator';\nimport { TransformIterator } from 'asynciterator';\nimport { LRUCache } from 'lru-cache';\nimport { Readable } from 'readable-stream';\nimport type { Algebra } from 'sparqlalgebrajs';\nimport { Factory } from 'sparqlalgebrajs';\nimport type { ISourceState } from './LinkedRdfSourcesAsyncRdfIterator';\nimport { MediatedLinkedRdfSourcesAsyncRdfIterator } from './MediatedLinkedRdfSourcesAsyncRdfIterator';\nimport { StreamingStoreMetadata } from './StreamingStoreMetadata';\n\nexport class QuerySourceHypermedia implements IQuerySource {\n public readonly referenceValue: string;\n public readonly firstUrl: string;\n public readonly forceSourceType?: string;\n public readonly aggregateStore: boolean;\n public readonly mediators: IMediatorArgs;\n public readonly logWarning: (warningMessage: string) => void;\n public readonly dataFactory: ComunicaDataFactory;\n public readonly bindingsFactory: BindingsFactory;\n\n /**\n * A cache for source URLs to source states.\n */\n public sourcesState: LRUCache<string, Promise<ISourceState>>;\n\n private readonly cacheSize: number;\n private readonly maxIterators: number;\n\n private readonly emitPartialCardinalities: boolean;\n\n public constructor(\n cacheSize: number,\n firstUrl: string,\n forceSourceType: string | undefined,\n maxIterators: number,\n aggregateStore: boolean,\n emitPartialCardinalities: boolean,\n mediators: IMediatorArgs,\n logWarning: (warningMessage: string) => void,\n dataFactory: ComunicaDataFactory,\n bindingsFactory: BindingsFactory,\n\n ) {\n this.referenceValue = firstUrl;\n this.cacheSize = cacheSize;\n this.firstUrl = firstUrl;\n this.forceSourceType = forceSourceType;\n this.maxIterators = maxIterators;\n this.mediators = mediators;\n this.aggregateStore = aggregateStore;\n this.emitPartialCardinalities = emitPartialCardinalities;\n this.logWarning = logWarning;\n this.dataFactory = dataFactory;\n this.bindingsFactory = bindingsFactory;\n this.sourcesState = new LRUCache<string, Promise<ISourceState>>({ max: this.cacheSize });\n }\n\n public async getSelectorShape(context: IActionContext): Promise<FragmentSelectorShape> {\n const source = await this.getSourceCached({ url: this.firstUrl }, {}, context, this.getAggregateStore(context));\n return source.source.getSelectorShape(context);\n }\n\n public queryBindings(\n operation: Algebra.Operation,\n context: IActionContext,\n options?: IQueryBindingsOptions,\n ): BindingsStream {\n // Optimized match with aggregated store if enabled and started.\n const aggregatedStore: IAggregatedStore | undefined = this.getAggregateStore(context);\n if (aggregatedStore && operation.type === 'pattern' && aggregatedStore.started) {\n return new QuerySourceRdfJs(\n aggregatedStore,\n context.getSafe(KeysInitQuery.dataFactory),\n this.bindingsFactory,\n ).queryBindings(operation, context);\n }\n\n // Initialize the sources state on first call\n if (this.sourcesState.size === 0) {\n this.getSourceCached({ url: this.firstUrl }, {}, context, aggregatedStore)\n .catch(error => it.destroy(error));\n }\n\n const dataFactory: ComunicaDataFactory = context.getSafe(KeysInitQuery.dataFactory);\n const algebraFactory = new Factory(dataFactory);\n const it: MediatedLinkedRdfSourcesAsyncRdfIterator = new MediatedLinkedRdfSourcesAsyncRdfIterator(\n this.cacheSize,\n operation,\n options,\n context,\n this.forceSourceType,\n this.firstUrl,\n this.maxIterators,\n (link, handledDatasets) => this.getSourceCached(link, handledDatasets, context, aggregatedStore),\n aggregatedStore,\n this.mediators.mediatorMetadataAccumulate,\n this.mediators.mediatorRdfResolveHypermediaLinks,\n this.mediators.mediatorRdfResolveHypermediaLinksQueue,\n dataFactory,\n algebraFactory,\n );\n if (aggregatedStore) {\n aggregatedStore.started = true;\n\n // Kickstart this iterator when derived iterators are created from the aggregatedStore,\n // otherwise the traversal process will not start if this iterator is not the first one to be consumed.\n const listener = (): void => it.kickstart();\n aggregatedStore.addIteratorCreatedListener(listener);\n it.on('end', () => aggregatedStore.removeIteratorCreatedListener(listener));\n }\n\n return it;\n }\n\n public queryQuads(operation: Algebra.Operation, context: IActionContext): AsyncIterator<RDF.Quad> {\n return new TransformIterator(async() => {\n const source = await this.getSourceCached({ url: this.firstUrl }, {}, context, this.getAggregateStore(context));\n return source.source.queryQuads(operation, context);\n });\n }\n\n public async queryBoolean(operation: Algebra.Ask, context: IActionContext): Promise<boolean> {\n const source = await this.getSourceCached({ url: this.firstUrl }, {}, context, this.getAggregateStore(context));\n return await source.source.queryBoolean(operation, context);\n }\n\n public async queryVoid(operation: Algebra.Update, context: IActionContext): Promise<void> {\n const source = await this.getSourceCached({ url: this.firstUrl }, {}, context, this.getAggregateStore(context));\n return await source.source.queryVoid(operation, context);\n }\n\n /**\n * Resolve a source for the given URL.\n * @param link A source link.\n * @param handledDatasets A hash of dataset identifiers that have already been handled.\n * @param context The action context.\n * @param aggregatedStore An optional aggregated store.\n */\n public async getSource(\n link: ILink,\n handledDatasets: Record<string, boolean>,\n context: IActionContext,\n aggregatedStore: IAggregatedStore | undefined,\n ): Promise<ISourceState> {\n // Include context entries from link\n if (link.context) {\n context = context.merge(link.context);\n }\n\n // Get the RDF representation of the given document\n let url = link.url;\n let quads: RDF.Stream;\n let metadata: Record<string, any>;\n if (this.forceSourceType === 'sparql' && context.get(KeysQueryOperation.querySources)?.length === 1) {\n // Skip metadata extraction if we're querying over just a single SPARQL endpoint.\n quads = new Readable();\n quads.read = () => null;\n ({ metadata } = await this.mediators.mediatorMetadataAccumulate.mediate({ context, mode: 'initialize' }));\n } else {\n try {\n const dereferenceRdfOutput: IActorDereferenceRdfOutput = await this.mediators.mediatorDereferenceRdf\n .mediate({ context, url });\n url = dereferenceRdfOutput.url;\n\n // Determine the metadata\n const rdfMetadataOutput: IActorRdfMetadataOutput = await this.mediators.mediatorMetadata.mediate(\n { context, url, quads: dereferenceRdfOutput.data, triples: dereferenceRdfOutput.metadata?.triples },\n );\n\n rdfMetadataOutput.data.on('error', () => {\n // Silence errors in the data stream,\n // as they will be emitted again in the metadata stream,\n // and will result in a promise rejection anyways.\n // If we don't do this, we end up with an unhandled error message\n });\n\n metadata = (await this.mediators.mediatorMetadataExtract.mediate({\n context,\n url,\n // The problem appears to be conflicting metadata keys here\n metadata: rdfMetadataOutput.metadata,\n headers: dereferenceRdfOutput.headers,\n requestTime: dereferenceRdfOutput.requestTime,\n })).metadata;\n quads = rdfMetadataOutput.data;\n\n // Optionally filter the resulting data\n if (link.transform) {\n quads = await link.transform(quads);\n }\n } catch (error: unknown) {\n // Make sure that dereference errors are only emitted once an actor really needs the read quads\n // This allows SPARQL endpoints that error on service description fetching to still be source-forcible\n quads = new Readable();\n quads.read = () => {\n setTimeout(() => quads.emit('error', error));\n return null;\n };\n ({ metadata } = await this.mediators.mediatorMetadataAccumulate.mediate({ context, mode: 'initialize' }));\n\n // Log as warning, because the quads above may not always be consumed (e.g. for SPARQL endpoints),\n // so the user would not be notified of something going wrong otherwise.\n this.logWarning(`Metadata extraction for ${url} failed: ${(<Error>error).message}`);\n }\n }\n\n // Aggregate all discovered quads into a store.\n aggregatedStore?.setBaseMetadata(<MetadataBindings> metadata, false);\n aggregatedStore?.containedSources.add(link.url);\n aggregatedStore?.import(quads);\n\n // Determine the source\n const { source, dataset } = await this.mediators.mediatorQuerySourceIdentifyHypermedia.mediate({\n context,\n forceSourceType: link.url === this.firstUrl ? this.forceSourceType : undefined,\n handledDatasets,\n metadata,\n quads,\n url,\n });\n\n if (dataset) {\n // Mark the dataset as applied\n // This is needed to make sure that things like QPF search forms are only applied once,\n // and next page links are followed after that.\n handledDatasets[dataset] = true;\n }\n\n return { link, source, metadata: <MetadataBindings> metadata, handledDatasets };\n }\n\n /**\n * Resolve a source for the given URL.\n * This will first try to retrieve the source from cache.\n * @param link A source ILink.\n * @param handledDatasets A hash of dataset identifiers that have already been handled.\n * @param context The action context.\n * @param aggregatedStore An optional aggregated store.\n */\n protected getSourceCached(\n link: ILink,\n handledDatasets: Record<string, boolean>,\n context: IActionContext,\n aggregatedStore: IAggregatedStore | undefined,\n ): Promise<ISourceState> {\n let source = this.sourcesState.get(link.url);\n if (source) {\n return source;\n }\n source = this.getSource(link, handledDatasets, context, aggregatedStore);\n if (link.url === this.firstUrl || aggregatedStore === undefined) {\n this.sourcesState.set(link.url, source);\n }\n return source;\n }\n\n public getAggregateStore(context: IActionContext): IAggregatedStore | undefined {\n let aggregatedStore: IAggregatedStore | undefined;\n if (this.aggregateStore) {\n const aggregatedStores: Map<string, IAggregatedStore> | undefined = context\n .get(KeysQuerySourceIdentify.hypermediaSourcesAggregatedStores);\n if (aggregatedStores) {\n aggregatedStore = aggregatedStores.get(this.firstUrl);\n if (!aggregatedStore) {\n aggregatedStore = new StreamingStoreMetadata(\n undefined,\n async(accumulatedMetadata, appendingMetadata) => <MetadataBindings>\n (await this.mediators.mediatorMetadataAccumulate.mediate({\n mode: 'append',\n accumulatedMetadata,\n appendingMetadata,\n context,\n })).metadata,\n this.emitPartialCardinalities,\n );\n aggregatedStores.set(this.firstUrl, aggregatedStore);\n }\n return aggregatedStore;\n }\n }\n }\n\n public toString(): string {\n return `QuerySourceHypermedia(${this.firstUrl})`;\n }\n}\n\nexport interface IMediatorArgs {\n mediatorDereferenceRdf: MediatorDereferenceRdf;\n mediatorMetadata: MediatorRdfMetadata;\n mediatorMetadataExtract: MediatorRdfMetadataExtract;\n mediatorMetadataAccumulate: MediatorRdfMetadataAccumulate;\n mediatorQuerySourceIdentifyHypermedia: MediatorQuerySourceIdentifyHypermedia;\n mediatorRdfResolveHypermediaLinks: MediatorRdfResolveHypermediaLinks;\n mediatorRdfResolveHypermediaLinksQueue: MediatorRdfResolveHypermediaLinksQueue;\n}\n"]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import type { EventEmitter } from 'node:events';
|
|
3
|
+
import type { IAggregatedStore, MetadataBindings } from '@comunica/types';
|
|
4
|
+
import type * as RDF from '@rdfjs/types';
|
|
5
|
+
import type { AsyncIterator } from 'asynciterator';
|
|
6
|
+
import { StreamingStore } from 'rdf-streaming-store';
|
|
7
|
+
/**
|
|
8
|
+
* A StreamingStore that returns an AsyncIterator with a valid MetadataQuads property.
|
|
9
|
+
*/
|
|
10
|
+
export declare class StreamingStoreMetadata extends StreamingStore implements IAggregatedStore {
|
|
11
|
+
started: boolean;
|
|
12
|
+
containedSources: Set<string>;
|
|
13
|
+
readonly runningIterators: Set<AsyncIterator<RDF.Quad>>;
|
|
14
|
+
protected readonly iteratorCreatedListeners: Set<() => void>;
|
|
15
|
+
protected readonly metadataAccumulator: (accumulatedMetadata: MetadataBindings, appendingMetadata: MetadataBindings) => Promise<MetadataBindings>;
|
|
16
|
+
/**
|
|
17
|
+
* Whether the StreamingStoreMetadata should emit updated partial cardinalities
|
|
18
|
+
* for each matching quad. Enabling this option may impact performance due to
|
|
19
|
+
* frequent {@link MetadataValidationState} invalidations and updates
|
|
20
|
+
*/
|
|
21
|
+
private readonly emitPartialCardinalities;
|
|
22
|
+
protected baseMetadata: MetadataBindings;
|
|
23
|
+
constructor(store: RDF.Store | undefined, metadataAccumulator: (accumulatedMetadata: MetadataBindings, appendingMetadata: MetadataBindings) => Promise<MetadataBindings>, emitPartialCardinalities: boolean);
|
|
24
|
+
import(stream: RDF.Stream): EventEmitter;
|
|
25
|
+
hasRunningIterators(): boolean;
|
|
26
|
+
match(subject?: RDF.Term | null, predicate?: RDF.Term | null, object?: RDF.Term | null, graph?: RDF.Term | null): AsyncIterator<RDF.Quad>;
|
|
27
|
+
setBaseMetadata(metadata: MetadataBindings, updateStates: boolean): void;
|
|
28
|
+
protected updateMetadataState(iterator: AsyncIterator<RDF.Quad>, count: number): void;
|
|
29
|
+
addIteratorCreatedListener(listener: () => void): void;
|
|
30
|
+
removeIteratorCreatedListener(listener: () => void): void;
|
|
31
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StreamingStoreMetadata = void 0;
|
|
4
|
+
const utils_iterator_1 = require("@comunica/utils-iterator");
|
|
5
|
+
const utils_metadata_1 = require("@comunica/utils-metadata");
|
|
6
|
+
const rdf_streaming_store_1 = require("rdf-streaming-store");
|
|
7
|
+
/**
|
|
8
|
+
* A StreamingStore that returns an AsyncIterator with a valid MetadataQuads property.
|
|
9
|
+
*/
|
|
10
|
+
class StreamingStoreMetadata extends rdf_streaming_store_1.StreamingStore {
|
|
11
|
+
constructor(store, metadataAccumulator, emitPartialCardinalities) {
|
|
12
|
+
super(store);
|
|
13
|
+
this.started = false;
|
|
14
|
+
this.containedSources = new Set();
|
|
15
|
+
this.runningIterators = new Set();
|
|
16
|
+
this.iteratorCreatedListeners = new Set();
|
|
17
|
+
this.baseMetadata = {
|
|
18
|
+
state: new utils_metadata_1.MetadataValidationState(),
|
|
19
|
+
cardinality: { type: 'exact', value: 0 },
|
|
20
|
+
variables: [],
|
|
21
|
+
};
|
|
22
|
+
this.metadataAccumulator = metadataAccumulator;
|
|
23
|
+
this.emitPartialCardinalities = emitPartialCardinalities;
|
|
24
|
+
}
|
|
25
|
+
import(stream) {
|
|
26
|
+
if (!this.ended) {
|
|
27
|
+
super.import(stream);
|
|
28
|
+
}
|
|
29
|
+
return stream;
|
|
30
|
+
}
|
|
31
|
+
hasRunningIterators() {
|
|
32
|
+
return this.runningIterators.size > 0;
|
|
33
|
+
}
|
|
34
|
+
match(subject, predicate, object, graph) {
|
|
35
|
+
// Wrap the raw stream in an AsyncIterator
|
|
36
|
+
const rawStream = super.match(subject, predicate, object, graph);
|
|
37
|
+
const iterator = new utils_iterator_1.ClosableTransformIterator(rawStream, {
|
|
38
|
+
autoStart: false,
|
|
39
|
+
onClose: () => {
|
|
40
|
+
// Running iterators are deleted once closed or destroyed
|
|
41
|
+
this.runningIterators.delete(iterator);
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
// Expose the metadata property containing the cardinality
|
|
45
|
+
let count = this.getStore().countQuads(subject, predicate, object, graph);
|
|
46
|
+
const metadata = {
|
|
47
|
+
state: new utils_metadata_1.MetadataValidationState(),
|
|
48
|
+
cardinality: {
|
|
49
|
+
type: 'estimate',
|
|
50
|
+
value: count,
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
iterator.setProperty('metadata', metadata);
|
|
54
|
+
iterator.setProperty('lastCount', count);
|
|
55
|
+
if (this.emitPartialCardinalities) {
|
|
56
|
+
// Every time a new quad is pushed into the iterator, update the metadata
|
|
57
|
+
rawStream.on('quad', () => {
|
|
58
|
+
iterator.setProperty('lastCount', ++count);
|
|
59
|
+
this.updateMetadataState(iterator, count);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
// Store all running iterators until they close or are destroyed
|
|
63
|
+
this.runningIterators.add(iterator);
|
|
64
|
+
// Invoke creation listeners
|
|
65
|
+
for (const listener of this.iteratorCreatedListeners) {
|
|
66
|
+
listener();
|
|
67
|
+
}
|
|
68
|
+
return iterator;
|
|
69
|
+
}
|
|
70
|
+
setBaseMetadata(metadata, updateStates) {
|
|
71
|
+
this.baseMetadata = { ...metadata };
|
|
72
|
+
this.baseMetadata.cardinality = { type: 'exact', value: 0 };
|
|
73
|
+
if (updateStates) {
|
|
74
|
+
for (const iterator of this.runningIterators) {
|
|
75
|
+
const count = iterator.getProperty('lastCount');
|
|
76
|
+
this.updateMetadataState(iterator, count);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
updateMetadataState(iterator, count) {
|
|
81
|
+
// Append the given cardinality to the base metadata
|
|
82
|
+
const metadataNew = {
|
|
83
|
+
state: new utils_metadata_1.MetadataValidationState(),
|
|
84
|
+
cardinality: {
|
|
85
|
+
type: 'estimate',
|
|
86
|
+
value: count,
|
|
87
|
+
},
|
|
88
|
+
variables: [],
|
|
89
|
+
};
|
|
90
|
+
this.metadataAccumulator(this.baseMetadata, metadataNew)
|
|
91
|
+
.then((accumulatedMetadata) => {
|
|
92
|
+
accumulatedMetadata.state = new utils_metadata_1.MetadataValidationState();
|
|
93
|
+
// Set the new metadata, and invalidate the previous state
|
|
94
|
+
const metadataToInvalidate = iterator.getProperty('metadata');
|
|
95
|
+
iterator.setProperty('metadata', accumulatedMetadata);
|
|
96
|
+
metadataToInvalidate?.state.invalidate();
|
|
97
|
+
})
|
|
98
|
+
.catch(() => {
|
|
99
|
+
// Void errors
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
addIteratorCreatedListener(listener) {
|
|
103
|
+
this.iteratorCreatedListeners.add(listener);
|
|
104
|
+
}
|
|
105
|
+
removeIteratorCreatedListener(listener) {
|
|
106
|
+
this.iteratorCreatedListeners.delete(listener);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
exports.StreamingStoreMetadata = StreamingStoreMetadata;
|
|
110
|
+
//# sourceMappingURL=StreamingStoreMetadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StreamingStoreMetadata.js","sourceRoot":"","sources":["StreamingStoreMetadata.ts"],"names":[],"mappings":";;;AAGA,6DAAqE;AACrE,6DAAmE;AAGnE,6DAAqD;AAErD;;GAEG;AACH,MAAa,sBAAuB,SAAQ,oCAAc;IAqBxD,YACE,KAA4B,EAC5B,mBACyG,EACzG,wBAAiC;QAEjC,KAAK,CAAC,KAAK,CAAC,CAAC;QA1BR,YAAO,GAAG,KAAK,CAAC;QAChB,qBAAgB,GAAG,IAAI,GAAG,EAAU,CAAC;QAC5B,qBAAgB,GAAiC,IAAI,GAAG,EAA2B,CAAC;QACjF,6BAAwB,GAAoB,IAAI,GAAG,EAAE,CAAC;QAW/D,iBAAY,GAAqB;YACzC,KAAK,EAAE,IAAI,wCAAuB,EAAE;YACpC,WAAW,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE;YACxC,SAAS,EAAE,EAAE;SACd,CAAC;QASA,IAAI,CAAC,mBAAmB,GAAG,mBAAmB,CAAC;QAC/C,IAAI,CAAC,wBAAwB,GAAG,wBAAwB,CAAC;IAC3D,CAAC;IAEe,MAAM,CAAC,MAAkB;QACvC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAEM,mBAAmB;QACxB,OAAO,IAAI,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,CAAC;IACxC,CAAC;IAEe,KAAK,CACnB,OAAyB,EACzB,SAA2B,EAC3B,MAAwB,EACxB,KAAuB;QAEvB,0CAA0C;QAC1C,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QACjE,MAAM,QAAQ,GAAG,IAAI,0CAAyB,CACtC,SAAS,EACf;YACE,SAAS,EAAE,KAAK;YAChB,OAAO,EAAE,GAAG,EAAE;gBACZ,yDAAyD;gBACzD,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACzC,CAAC;SACF,CACF,CAAC;QAEF,0DAA0D;QAC1D,IAAI,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,OAAQ,EAAE,SAAU,EAAE,MAAO,EAAE,KAAM,CAAC,CAAC;QAC9E,MAAM,QAAQ,GAAkB;YAC9B,KAAK,EAAE,IAAI,wCAAuB,EAAE;YACpC,WAAW,EAAE;gBACX,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE,KAAK;aACb;SACF,CAAC;QACF,QAAQ,CAAC,WAAW,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAC3C,QAAQ,CAAC,WAAW,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QAEzC,IAAI,IAAI,CAAC,wBAAwB,EAAE,CAAC;YAClC,yEAAyE;YACzE,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;gBACxB,QAAQ,CAAC,WAAW,CAAC,WAAW,EAAE,EAAE,KAAK,CAAC,CAAC;gBAC3C,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC5C,CAAC,CAAC,CAAC;QACL,CAAC;QAED,gEAAgE;QAChE,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAEpC,4BAA4B;QAC5B,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,wBAAwB,EAAE,CAAC;YACrD,QAAQ,EAAE,CAAC;QACb,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAEM,eAAe,CAAC,QAA0B,EAAE,YAAqB;QACtE,IAAI,CAAC,YAAY,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QACpC,IAAI,CAAC,YAAY,CAAC,WAAW,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAE5D,IAAI,YAAY,EAAE,CAAC;YACjB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBAC7C,MAAM,KAAK,GAAW,QAAQ,CAAC,WAAW,CAAC,WAAW,CAAE,CAAC;gBACzD,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;IACH,CAAC;IAES,mBAAmB,CAAC,QAAiC,EAAE,KAAa;QAC5E,oDAAoD;QACpD,MAAM,WAAW,GAAqB;YACpC,KAAK,EAAE,IAAI,wCAAuB,EAAE;YACpC,WAAW,EAAE;gBACX,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE,KAAK;aACb;YACD,SAAS,EAAE,EAAE;SACd,CAAC;QAEF,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC;aACrD,IAAI,CAAC,CAAC,mBAAmB,EAAE,EAAE;YAC5B,mBAAmB,CAAC,KAAK,GAAG,IAAI,wCAAuB,EAAE,CAAC;YAE1D,0DAA0D;YAC1D,MAAM,oBAAoB,GAAG,QAAQ,CAAC,WAAW,CAAgB,UAAU,CAAC,CAAC;YAC7E,QAAQ,CAAC,WAAW,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAC;YACtD,oBAAoB,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC;QAC3C,CAAC,CAAC;aACD,KAAK,CAAC,GAAG,EAAE;YACV,cAAc;QAChB,CAAC,CAAC,CAAC;IACP,CAAC;IAEM,0BAA0B,CAAC,QAAoB;QACpD,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAEM,6BAA6B,CAAC,QAAoB;QACvD,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACjD,CAAC;CACF;AAzID,wDAyIC","sourcesContent":["// eslint-disable-next-line import/no-nodejs-modules\nimport type { EventEmitter } from 'node:events';\nimport type { MetadataQuads, IAggregatedStore, MetadataBindings } from '@comunica/types';\nimport { ClosableTransformIterator } from '@comunica/utils-iterator';\nimport { MetadataValidationState } from '@comunica/utils-metadata';\nimport type * as RDF from '@rdfjs/types';\nimport type { AsyncIterator } from 'asynciterator';\nimport { StreamingStore } from 'rdf-streaming-store';\n\n/**\n * A StreamingStore that returns an AsyncIterator with a valid MetadataQuads property.\n */\nexport class StreamingStoreMetadata extends StreamingStore implements IAggregatedStore {\n public started = false;\n public containedSources = new Set<string>();\n public readonly runningIterators: Set<AsyncIterator<RDF.Quad>> = new Set<AsyncIterator<RDF.Quad>>();\n protected readonly iteratorCreatedListeners: Set<() => void> = new Set();\n protected readonly metadataAccumulator:\n (accumulatedMetadata: MetadataBindings, appendingMetadata: MetadataBindings) => Promise<MetadataBindings>;\n\n /**\n * Whether the StreamingStoreMetadata should emit updated partial cardinalities\n * for each matching quad. Enabling this option may impact performance due to\n * frequent {@link MetadataValidationState} invalidations and updates\n */\n private readonly emitPartialCardinalities: boolean;\n\n protected baseMetadata: MetadataBindings = {\n state: new MetadataValidationState(),\n cardinality: { type: 'exact', value: 0 },\n variables: [],\n };\n\n public constructor(\n store: RDF.Store | undefined,\n metadataAccumulator:\n (accumulatedMetadata: MetadataBindings, appendingMetadata: MetadataBindings) => Promise<MetadataBindings>,\n emitPartialCardinalities: boolean,\n ) {\n super(store);\n this.metadataAccumulator = metadataAccumulator;\n this.emitPartialCardinalities = emitPartialCardinalities;\n }\n\n public override import(stream: RDF.Stream): EventEmitter {\n if (!this.ended) {\n super.import(stream);\n }\n return stream;\n }\n\n public hasRunningIterators(): boolean {\n return this.runningIterators.size > 0;\n }\n\n public override match(\n subject?: RDF.Term | null,\n predicate?: RDF.Term | null,\n object?: RDF.Term | null,\n graph?: RDF.Term | null,\n ): AsyncIterator<RDF.Quad> {\n // Wrap the raw stream in an AsyncIterator\n const rawStream = super.match(subject, predicate, object, graph);\n const iterator = new ClosableTransformIterator<RDF.Quad, RDF.Quad>(\n <any> rawStream,\n {\n autoStart: false,\n onClose: () => {\n // Running iterators are deleted once closed or destroyed\n this.runningIterators.delete(iterator);\n },\n },\n );\n\n // Expose the metadata property containing the cardinality\n let count = this.getStore().countQuads(subject!, predicate!, object!, graph!);\n const metadata: MetadataQuads = {\n state: new MetadataValidationState(),\n cardinality: {\n type: 'estimate',\n value: count,\n },\n };\n iterator.setProperty('metadata', metadata);\n iterator.setProperty('lastCount', count);\n\n if (this.emitPartialCardinalities) {\n // Every time a new quad is pushed into the iterator, update the metadata\n rawStream.on('quad', () => {\n iterator.setProperty('lastCount', ++count);\n this.updateMetadataState(iterator, count);\n });\n }\n\n // Store all running iterators until they close or are destroyed\n this.runningIterators.add(iterator);\n\n // Invoke creation listeners\n for (const listener of this.iteratorCreatedListeners) {\n listener();\n }\n\n return iterator;\n }\n\n public setBaseMetadata(metadata: MetadataBindings, updateStates: boolean): void {\n this.baseMetadata = { ...metadata };\n this.baseMetadata.cardinality = { type: 'exact', value: 0 };\n\n if (updateStates) {\n for (const iterator of this.runningIterators) {\n const count: number = iterator.getProperty('lastCount')!;\n this.updateMetadataState(iterator, count);\n }\n }\n }\n\n protected updateMetadataState(iterator: AsyncIterator<RDF.Quad>, count: number): void {\n // Append the given cardinality to the base metadata\n const metadataNew: MetadataBindings = {\n state: new MetadataValidationState(),\n cardinality: {\n type: 'estimate',\n value: count,\n },\n variables: [],\n };\n\n this.metadataAccumulator(this.baseMetadata, metadataNew)\n .then((accumulatedMetadata) => {\n accumulatedMetadata.state = new MetadataValidationState();\n\n // Set the new metadata, and invalidate the previous state\n const metadataToInvalidate = iterator.getProperty<MetadataQuads>('metadata');\n iterator.setProperty('metadata', accumulatedMetadata);\n metadataToInvalidate?.state.invalidate();\n })\n .catch(() => {\n // Void errors\n });\n }\n\n public addIteratorCreatedListener(listener: () => void): void {\n this.iteratorCreatedListeners.add(listener);\n }\n\n public removeIteratorCreatedListener(listener: () => void): void {\n this.iteratorCreatedListeners.delete(listener);\n }\n}\n"]}
|
package/lib/index.d.ts
CHANGED
|
File without changes
|
package/lib/index.js
CHANGED
|
File without changes
|
package/lib/index.js.map
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@comunica/actor-query-source-identify-hypermedia",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.5.0",
|
|
4
4
|
"description": "A hypermedia query-source-identify actor",
|
|
5
5
|
"lsd:module": true,
|
|
6
6
|
"license": "MIT",
|
|
@@ -41,21 +41,28 @@
|
|
|
41
41
|
"build:components": "componentsjs-generator"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@comunica/
|
|
45
|
-
"@comunica/bus-
|
|
46
|
-
"@comunica/bus-
|
|
47
|
-
"@comunica/bus-
|
|
48
|
-
"@comunica/bus-
|
|
49
|
-
"@comunica/bus-rdf-
|
|
50
|
-
"@comunica/
|
|
51
|
-
"@comunica/
|
|
52
|
-
"@comunica/
|
|
53
|
-
"@comunica/
|
|
54
|
-
"@comunica/
|
|
55
|
-
"@comunica/
|
|
44
|
+
"@comunica/actor-query-source-identify-rdfjs": "^4.5.0",
|
|
45
|
+
"@comunica/bus-dereference-rdf": "^4.5.0",
|
|
46
|
+
"@comunica/bus-merge-bindings-context": "^4.5.0",
|
|
47
|
+
"@comunica/bus-query-source-identify": "^4.5.0",
|
|
48
|
+
"@comunica/bus-query-source-identify-hypermedia": "^4.5.0",
|
|
49
|
+
"@comunica/bus-rdf-metadata": "^4.5.0",
|
|
50
|
+
"@comunica/bus-rdf-metadata-accumulate": "^4.5.0",
|
|
51
|
+
"@comunica/bus-rdf-metadata-extract": "^4.5.0",
|
|
52
|
+
"@comunica/bus-rdf-resolve-hypermedia-links": "^4.5.0",
|
|
53
|
+
"@comunica/bus-rdf-resolve-hypermedia-links-queue": "^4.5.0",
|
|
54
|
+
"@comunica/context-entries": "^4.5.0",
|
|
55
|
+
"@comunica/core": "^4.5.0",
|
|
56
|
+
"@comunica/types": "^4.5.0",
|
|
57
|
+
"@comunica/utils-bindings-factory": "^4.5.0",
|
|
58
|
+
"@comunica/utils-iterator": "^4.5.0",
|
|
59
|
+
"@comunica/utils-metadata": "^4.5.0",
|
|
56
60
|
"@rdfjs/types": "*",
|
|
57
|
-
"asynciterator": "^3.
|
|
58
|
-
"lru-cache": "^10.0.0"
|
|
61
|
+
"asynciterator": "^3.9.0",
|
|
62
|
+
"lru-cache": "^10.0.0",
|
|
63
|
+
"rdf-streaming-store": "^2.1.1",
|
|
64
|
+
"readable-stream": "^4.5.2",
|
|
65
|
+
"sparqlalgebrajs": "^5.0.2"
|
|
59
66
|
},
|
|
60
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "2bcd98c387a021fc5c08d375793c205ca3d1bf0d"
|
|
61
68
|
}
|