@comunica/actor-query-source-identify-hypermedia 4.5.0 → 5.0.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 +5 -11
- package/components/ActorQuerySourceIdentifyHypermedia.jsonld +24 -134
- package/components/QuerySourceHypermedia.jsonld +20 -117
- package/components/components.jsonld +1 -1
- package/components/context.jsonld +13 -85
- package/lib/ActorQuerySourceIdentifyHypermedia.d.ts +5 -41
- package/lib/ActorQuerySourceIdentifyHypermedia.js +19 -8
- package/lib/ActorQuerySourceIdentifyHypermedia.js.map +1 -1
- package/lib/LinkedRdfSourcesAsyncRdfIterator.d.ts +9 -6
- package/lib/LinkedRdfSourcesAsyncRdfIterator.js +19 -16
- package/lib/LinkedRdfSourcesAsyncRdfIterator.js.map +1 -1
- package/lib/MediatedLinkedRdfSourcesAsyncRdfIterator.d.ts +5 -17
- package/lib/MediatedLinkedRdfSourcesAsyncRdfIterator.js +11 -92
- package/lib/MediatedLinkedRdfSourcesAsyncRdfIterator.js.map +1 -1
- package/lib/QuerySourceHypermedia.d.ts +10 -22
- package/lib/QuerySourceHypermedia.js +47 -136
- package/lib/QuerySourceHypermedia.js.map +1 -1
- package/lib/index.d.ts +0 -0
- package/lib/index.js +0 -0
- package/lib/index.js.map +0 -0
- package/package.json +16 -23
- package/lib/StreamingStoreMetadata.d.ts +0 -31
- package/lib/StreamingStoreMetadata.js +0 -110
- package/lib/StreamingStoreMetadata.js.map +0 -1
|
@@ -4,93 +4,31 @@ exports.MediatedLinkedRdfSourcesAsyncRdfIterator = void 0;
|
|
|
4
4
|
const context_entries_1 = require("@comunica/context-entries");
|
|
5
5
|
const LinkedRdfSourcesAsyncRdfIterator_1 = require("./LinkedRdfSourcesAsyncRdfIterator");
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* A quad iterator that can iterate over consecutive RDF sources
|
|
8
8
|
* that are determined using the rdf-resolve-hypermedia-links bus.
|
|
9
9
|
*
|
|
10
10
|
* @see LinkedRdfSourcesAsyncRdfIterator
|
|
11
11
|
*/
|
|
12
12
|
class MediatedLinkedRdfSourcesAsyncRdfIterator extends LinkedRdfSourcesAsyncRdfIterator_1.LinkedRdfSourcesAsyncRdfIterator {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
mediatorMetadataAccumulate;
|
|
14
|
+
mediatorRdfResolveHypermediaLinks;
|
|
15
|
+
mediatorRdfResolveHypermediaLinksQueue;
|
|
16
|
+
handledUrls;
|
|
17
|
+
linkQueue;
|
|
18
|
+
constructor(operation, queryBindingsOptions, context, firstLink, maxIterators, sourceStateGetter, mediatorMetadataAccumulate, mediatorRdfResolveHypermediaLinks, mediatorRdfResolveHypermediaLinksQueue) {
|
|
19
|
+
super(operation, queryBindingsOptions, context, firstLink, maxIterators, sourceStateGetter);
|
|
20
20
|
this.mediatorMetadataAccumulate = mediatorMetadataAccumulate;
|
|
21
21
|
this.mediatorRdfResolveHypermediaLinks = mediatorRdfResolveHypermediaLinks;
|
|
22
22
|
this.mediatorRdfResolveHypermediaLinksQueue = mediatorRdfResolveHypermediaLinksQueue;
|
|
23
|
-
this.handledUrls = { [
|
|
24
|
-
this.aggregatedStore = aggregatedStore;
|
|
25
|
-
this.dataFactory = dataFactory;
|
|
26
|
-
this.algebraFactory = algebraFactory;
|
|
27
|
-
}
|
|
28
|
-
// Mark the aggregated store as ended once we trigger the closing or destroying of this iterator.
|
|
29
|
-
// We don't override _end, because that would mean that we have to wait
|
|
30
|
-
// until the buffer of this iterator must be fully consumed, which will not always be the case.
|
|
31
|
-
close() {
|
|
32
|
-
if (!this.aggregatedStore) {
|
|
33
|
-
super.close();
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
this.getLinkQueue()
|
|
37
|
-
.then((linkQueue) => {
|
|
38
|
-
if (this.isCloseable(linkQueue, false)) {
|
|
39
|
-
// Wait a tick before ending the aggregatedStore, to ensure that pending match() calls to it have started.
|
|
40
|
-
setTimeout(() => this.aggregatedStore.end());
|
|
41
|
-
super.close();
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
this.wasForcefullyClosed = true;
|
|
45
|
-
}
|
|
46
|
-
})
|
|
47
|
-
.catch(error => super.destroy(error));
|
|
48
|
-
}
|
|
49
|
-
destroy(cause) {
|
|
50
|
-
if (!this.aggregatedStore) {
|
|
51
|
-
super.destroy(cause);
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
this.getLinkQueue()
|
|
55
|
-
.then((linkQueue) => {
|
|
56
|
-
if (cause ?? this.isCloseable(linkQueue, false)) {
|
|
57
|
-
// Wait a tick before ending the aggregatedStore, to ensure that pending match() calls to it have started.
|
|
58
|
-
setTimeout(() => this.aggregatedStore.end());
|
|
59
|
-
super.destroy(cause);
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
this.wasForcefullyClosed = true;
|
|
63
|
-
}
|
|
64
|
-
})
|
|
65
|
-
.catch(error => super.destroy(error));
|
|
23
|
+
this.handledUrls = { [firstLink.url]: true };
|
|
66
24
|
}
|
|
67
25
|
isCloseable(linkQueue, requireQueueEmpty) {
|
|
68
|
-
return (requireQueueEmpty ? linkQueue.isEmpty() :
|
|
69
|
-
!this.areIteratorsRunning();
|
|
70
|
-
}
|
|
71
|
-
canStartNewIterator() {
|
|
72
|
-
// Also allow sub-iterators to be started if the aggregated store has at least one running iterator.
|
|
73
|
-
// We need this because there are cases where these running iterators will be consumed before this linked iterator.
|
|
74
|
-
// We can keep traversing if the iterator was forcefully closed and there are still running iterators on the
|
|
75
|
-
// aggregated store, as this might happen when sub-queries are spawned by the bind-join.
|
|
76
|
-
// Whenever the store is forcefully closed (like due to a limit being reached) and there are no iterators on the
|
|
77
|
-
// store, traversal should stop.
|
|
78
|
-
return (!this.wasForcefullyClosed ||
|
|
79
|
-
(this.aggregatedStore !== undefined && this.aggregatedStore.hasRunningIterators())) &&
|
|
80
|
-
super.canStartNewIterator();
|
|
81
|
-
}
|
|
82
|
-
canStartNewIteratorConsiderReadable() {
|
|
83
|
-
return !this.aggregatedStore;
|
|
84
|
-
}
|
|
85
|
-
isRunning() {
|
|
86
|
-
// Same as above
|
|
87
|
-
// eslint-disable-next-line ts/prefer-nullish-coalescing
|
|
88
|
-
return (this.aggregatedStore && this.aggregatedStore.hasRunningIterators()) || !this.done;
|
|
26
|
+
return (requireQueueEmpty ? linkQueue.isEmpty() : linkQueue.isEmpty()) && !this.areIteratorsRunning();
|
|
89
27
|
}
|
|
90
28
|
getLinkQueue() {
|
|
91
29
|
if (!this.linkQueue) {
|
|
92
30
|
this.linkQueue = this.mediatorRdfResolveHypermediaLinksQueue
|
|
93
|
-
.mediate({
|
|
31
|
+
.mediate({ context: this.context })
|
|
94
32
|
.then(result => result.linkQueue);
|
|
95
33
|
}
|
|
96
34
|
return this.linkQueue;
|
|
@@ -119,21 +57,6 @@ class MediatedLinkedRdfSourcesAsyncRdfIterator extends LinkedRdfSourcesAsyncRdfI
|
|
|
119
57
|
return [];
|
|
120
58
|
}
|
|
121
59
|
}
|
|
122
|
-
startIterator(startSource) {
|
|
123
|
-
if (this.aggregatedStore && !this.aggregatedStore.containedSources.has(startSource.link.url)) {
|
|
124
|
-
// A source that has been cached due to earlier query executions may not be part of the aggregated store yet.
|
|
125
|
-
// In that case, we add all quads from that source to the aggregated store.
|
|
126
|
-
this.aggregatedStore?.containedSources.add(startSource.link.url);
|
|
127
|
-
const stream = startSource.source.queryBindings(this.algebraFactory.createPattern(this.dataFactory.variable('s'), this.dataFactory.variable('p'), this.dataFactory.variable('o'), this.dataFactory.variable('g')), this.context.set(context_entries_1.KeysQueryOperation.unionDefaultGraph, true)).map(bindings => this.dataFactory.quad(bindings.get('s'), bindings.get('p'), bindings.get('o'), bindings.get('g')));
|
|
128
|
-
this.aggregatedStore.import(stream)
|
|
129
|
-
.on('end', () => {
|
|
130
|
-
super.startIterator(startSource);
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
super.startIterator(startSource);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
60
|
async accumulateMetadata(accumulatedMetadata, appendingMetadata) {
|
|
138
61
|
return (await this.mediatorMetadataAccumulate.mediate({
|
|
139
62
|
mode: 'append',
|
|
@@ -142,10 +65,6 @@ class MediatedLinkedRdfSourcesAsyncRdfIterator extends LinkedRdfSourcesAsyncRdfI
|
|
|
142
65
|
context: this.context,
|
|
143
66
|
})).metadata;
|
|
144
67
|
}
|
|
145
|
-
updateMetadata(metadataNew) {
|
|
146
|
-
super.updateMetadata(metadataNew);
|
|
147
|
-
this.aggregatedStore?.setBaseMetadata(metadataNew, true);
|
|
148
|
-
}
|
|
149
68
|
}
|
|
150
69
|
exports.MediatedLinkedRdfSourcesAsyncRdfIterator = MediatedLinkedRdfSourcesAsyncRdfIterator;
|
|
151
70
|
//# sourceMappingURL=MediatedLinkedRdfSourcesAsyncRdfIterator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MediatedLinkedRdfSourcesAsyncRdfIterator.js","sourceRoot":"","sources":["MediatedLinkedRdfSourcesAsyncRdfIterator.ts"],"names":[],"mappings":"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","sourcesContent":["import type { MediatorRdfMetadataAccumulate } from '@comunica/bus-rdf-metadata-accumulate';\nimport type { MediatorRdfResolveHypermediaLinks } from '@comunica/bus-rdf-resolve-hypermedia-links';\nimport type {\n ILinkQueue,\n MediatorRdfResolveHypermediaLinksQueue,\n} from '@comunica/bus-rdf-resolve-hypermedia-links-queue';\nimport { KeysQueryOperation, KeysStatistics } from '@comunica/context-entries';\nimport type {\n ComunicaDataFactory,\n IActionContext,\n IAggregatedStore,\n IQueryBindingsOptions,\n MetadataBindings,\n ILink,\n IStatisticBase,\n IDiscoverEventData,\n} from '@comunica/types';\nimport type * as RDF from '@rdfjs/types';\nimport type { Algebra, Factory } from 'sparqlalgebrajs';\nimport type { SourceStateGetter, ISourceState } from './LinkedRdfSourcesAsyncRdfIterator';\nimport { LinkedRdfSourcesAsyncRdfIterator } from './LinkedRdfSourcesAsyncRdfIterator';\n\n/**\n * An quad iterator that can iterate over consecutive RDF sources\n * that are determined using the rdf-resolve-hypermedia-links bus.\n *\n * @see LinkedRdfSourcesAsyncRdfIterator\n */\nexport class MediatedLinkedRdfSourcesAsyncRdfIterator extends LinkedRdfSourcesAsyncRdfIterator {\n private readonly mediatorMetadataAccumulate: MediatorRdfMetadataAccumulate;\n private readonly mediatorRdfResolveHypermediaLinks: MediatorRdfResolveHypermediaLinks;\n private readonly mediatorRdfResolveHypermediaLinksQueue: MediatorRdfResolveHypermediaLinksQueue;\n private readonly forceSourceType?: string;\n private readonly handledUrls: Record<string, boolean>;\n private readonly aggregatedStore: IAggregatedStore | undefined;\n private readonly dataFactory: ComunicaDataFactory;\n private readonly algebraFactory: Factory;\n private linkQueue: Promise<ILinkQueue> | undefined;\n private wasForcefullyClosed = false;\n\n public constructor(\n cacheSize: number,\n operation: Algebra.Operation,\n queryBindingsOptions: IQueryBindingsOptions | undefined,\n context: IActionContext,\n forceSourceType: string | undefined,\n firstUrl: string,\n maxIterators: number,\n sourceStateGetter: SourceStateGetter,\n aggregatedStore: IAggregatedStore | undefined,\n mediatorMetadataAccumulate: MediatorRdfMetadataAccumulate,\n mediatorRdfResolveHypermediaLinks: MediatorRdfResolveHypermediaLinks,\n mediatorRdfResolveHypermediaLinksQueue: MediatorRdfResolveHypermediaLinksQueue,\n dataFactory: ComunicaDataFactory,\n algebraFactory: Factory,\n ) {\n super(\n cacheSize,\n operation,\n queryBindingsOptions,\n context,\n firstUrl,\n maxIterators,\n sourceStateGetter,\n // Buffersize must be infinite for an aggregated store because it must keep filling until there are no more\n // derived iterators in the aggregated store.\n aggregatedStore ? { maxBufferSize: Number.POSITIVE_INFINITY } : undefined,\n );\n this.forceSourceType = forceSourceType;\n this.mediatorMetadataAccumulate = mediatorMetadataAccumulate;\n this.mediatorRdfResolveHypermediaLinks = mediatorRdfResolveHypermediaLinks;\n this.mediatorRdfResolveHypermediaLinksQueue = mediatorRdfResolveHypermediaLinksQueue;\n this.handledUrls = { [firstUrl]: true };\n this.aggregatedStore = aggregatedStore;\n this.dataFactory = dataFactory;\n this.algebraFactory = algebraFactory;\n }\n\n // Mark the aggregated store as ended once we trigger the closing or destroying of this iterator.\n // We don't override _end, because that would mean that we have to wait\n // until the buffer of this iterator must be fully consumed, which will not always be the case.\n\n public override close(): void {\n if (!this.aggregatedStore) {\n super.close();\n return;\n }\n\n this.getLinkQueue()\n .then((linkQueue) => {\n if (this.isCloseable(linkQueue, false)) {\n // Wait a tick before ending the aggregatedStore, to ensure that pending match() calls to it have started.\n setTimeout(() => this.aggregatedStore!.end());\n super.close();\n } else {\n this.wasForcefullyClosed = true;\n }\n })\n .catch(error => super.destroy(error));\n }\n\n public override destroy(cause?: Error): void {\n if (!this.aggregatedStore) {\n super.destroy(cause);\n return;\n }\n\n this.getLinkQueue()\n .then((linkQueue) => {\n if (cause ?? this.isCloseable(linkQueue, false)) {\n // Wait a tick before ending the aggregatedStore, to ensure that pending match() calls to it have started.\n setTimeout(() => this.aggregatedStore!.end());\n super.destroy(cause);\n } else {\n this.wasForcefullyClosed = true;\n }\n })\n .catch(error => super.destroy(error));\n }\n\n protected override isCloseable(linkQueue: ILinkQueue, requireQueueEmpty: boolean): boolean {\n return (requireQueueEmpty ? linkQueue.isEmpty() : this.wasForcefullyClosed || linkQueue.isEmpty()) &&\n !this.areIteratorsRunning();\n }\n\n protected override canStartNewIterator(): boolean {\n // Also allow sub-iterators to be started if the aggregated store has at least one running iterator.\n // We need this because there are cases where these running iterators will be consumed before this linked iterator.\n // We can keep traversing if the iterator was forcefully closed and there are still running iterators on the\n // aggregated store, as this might happen when sub-queries are spawned by the bind-join.\n // Whenever the store is forcefully closed (like due to a limit being reached) and there are no iterators on the\n // store, traversal should stop.\n return (!this.wasForcefullyClosed ||\n (this.aggregatedStore !== undefined && this.aggregatedStore.hasRunningIterators())) &&\n super.canStartNewIterator();\n }\n\n protected override canStartNewIteratorConsiderReadable(): boolean {\n return !this.aggregatedStore;\n }\n\n protected override isRunning(): boolean {\n // Same as above\n // eslint-disable-next-line ts/prefer-nullish-coalescing\n return (this.aggregatedStore && this.aggregatedStore.hasRunningIterators()) || !this.done;\n }\n\n public getLinkQueue(): Promise<ILinkQueue> {\n if (!this.linkQueue) {\n this.linkQueue = this.mediatorRdfResolveHypermediaLinksQueue\n .mediate({ firstUrl: this.firstUrl, context: this.context })\n .then(result => result.linkQueue);\n }\n return this.linkQueue;\n }\n\n protected async getSourceLinks(metadata: Record<string, any>, startSource: ISourceState): Promise<ILink[]> {\n try {\n const { links } = await this.mediatorRdfResolveHypermediaLinks.mediate({ context: this.context, metadata });\n // Update discovery event statistic if available\n const traversalTracker: IStatisticBase<IDiscoverEventData> | undefined =\n this.context.get(KeysStatistics.discoveredLinks);\n if (traversalTracker) {\n for (const link of links) {\n traversalTracker.updateStatistic({ url: link.url, metadata: { ...link.metadata }}, startSource.link);\n }\n }\n\n // Filter URLs to avoid cyclic next-page loops\n return links.filter((link) => {\n if (this.handledUrls[link.url]) {\n return false;\n }\n this.handledUrls[link.url] = true;\n return true;\n });\n } catch {\n // No next URLs may be available, for example when we've reached the end of a Hydra next-page sequence.\n return [];\n }\n }\n\n protected override startIterator(startSource: ISourceState): void {\n if (this.aggregatedStore && !this.aggregatedStore.containedSources.has(startSource.link.url)) {\n // A source that has been cached due to earlier query executions may not be part of the aggregated store yet.\n // In that case, we add all quads from that source to the aggregated store.\n this.aggregatedStore?.containedSources.add(startSource.link.url);\n const stream = startSource.source.queryBindings(\n this.algebraFactory.createPattern(\n this.dataFactory.variable('s'),\n this.dataFactory.variable('p'),\n this.dataFactory.variable('o'),\n this.dataFactory.variable('g'),\n ),\n this.context.set(KeysQueryOperation.unionDefaultGraph, true),\n ).map(bindings => (<RDF.DataFactory<RDF.BaseQuad>> this.dataFactory).quad(\n bindings.get('s')!,\n bindings.get('p')!,\n bindings.get('o')!,\n bindings.get('g'),\n ));\n this.aggregatedStore.import(<RDF.Stream> stream)\n .on('end', () => {\n super.startIterator(startSource);\n });\n } else {\n super.startIterator(startSource);\n }\n }\n\n public async accumulateMetadata(\n accumulatedMetadata: MetadataBindings,\n appendingMetadata: MetadataBindings,\n ): Promise<MetadataBindings> {\n return <MetadataBindings> (await this.mediatorMetadataAccumulate.mediate({\n mode: 'append',\n accumulatedMetadata,\n appendingMetadata,\n context: this.context,\n })).metadata;\n }\n\n protected override updateMetadata(metadataNew: MetadataBindings): void {\n super.updateMetadata(metadataNew);\n this.aggregatedStore?.setBaseMetadata(metadataNew, true);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"MediatedLinkedRdfSourcesAsyncRdfIterator.js","sourceRoot":"","sources":["MediatedLinkedRdfSourcesAsyncRdfIterator.ts"],"names":[],"mappings":"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","sourcesContent":["import 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 { KeysStatistics } from '@comunica/context-entries';\nimport type {\n IActionContext,\n IQueryBindingsOptions,\n MetadataBindings,\n ILink,\n IStatisticBase,\n IDiscoverEventData,\n ILinkQueue,\n} from '@comunica/types';\nimport type { Algebra } from '@comunica/utils-algebra';\nimport type { SourceStateGetter, ISourceState } from './LinkedRdfSourcesAsyncRdfIterator';\nimport { LinkedRdfSourcesAsyncRdfIterator } from './LinkedRdfSourcesAsyncRdfIterator';\n\n/**\n * A quad iterator that can iterate over consecutive RDF sources\n * that are determined using the rdf-resolve-hypermedia-links bus.\n *\n * @see LinkedRdfSourcesAsyncRdfIterator\n */\nexport class MediatedLinkedRdfSourcesAsyncRdfIterator extends LinkedRdfSourcesAsyncRdfIterator {\n private readonly mediatorMetadataAccumulate: MediatorRdfMetadataAccumulate;\n private readonly mediatorRdfResolveHypermediaLinks: MediatorRdfResolveHypermediaLinks;\n private readonly mediatorRdfResolveHypermediaLinksQueue: MediatorRdfResolveHypermediaLinksQueue;\n private readonly handledUrls: Record<string, boolean>;\n private linkQueue: Promise<ILinkQueue> | undefined;\n\n public constructor(\n operation: Algebra.Operation,\n queryBindingsOptions: IQueryBindingsOptions | undefined,\n context: IActionContext,\n firstLink: ILink,\n maxIterators: number,\n sourceStateGetter: SourceStateGetter,\n mediatorMetadataAccumulate: MediatorRdfMetadataAccumulate,\n mediatorRdfResolveHypermediaLinks: MediatorRdfResolveHypermediaLinks,\n mediatorRdfResolveHypermediaLinksQueue: MediatorRdfResolveHypermediaLinksQueue,\n ) {\n super(\n operation,\n queryBindingsOptions,\n context,\n firstLink,\n maxIterators,\n sourceStateGetter,\n );\n this.mediatorMetadataAccumulate = mediatorMetadataAccumulate;\n this.mediatorRdfResolveHypermediaLinks = mediatorRdfResolveHypermediaLinks;\n this.mediatorRdfResolveHypermediaLinksQueue = mediatorRdfResolveHypermediaLinksQueue;\n this.handledUrls = { [firstLink.url]: true };\n }\n\n protected override isCloseable(linkQueue: ILinkQueue, requireQueueEmpty: boolean): boolean {\n return (requireQueueEmpty ? linkQueue.isEmpty() : linkQueue.isEmpty()) && !this.areIteratorsRunning();\n }\n\n public getLinkQueue(): Promise<ILinkQueue> {\n if (!this.linkQueue) {\n this.linkQueue = this.mediatorRdfResolveHypermediaLinksQueue\n .mediate({ context: this.context })\n .then(result => result.linkQueue);\n }\n return this.linkQueue;\n }\n\n protected async getSourceLinks(metadata: Record<string, any>, startSource: ISourceState): Promise<ILink[]> {\n try {\n const { links } = await this.mediatorRdfResolveHypermediaLinks.mediate({ context: this.context, metadata });\n // Update discovery event statistic if available\n const traversalTracker: IStatisticBase<IDiscoverEventData> | undefined =\n this.context.get(KeysStatistics.discoveredLinks);\n if (traversalTracker) {\n for (const link of links) {\n traversalTracker.updateStatistic({ url: link.url, metadata: { ...link.metadata }}, startSource.link);\n }\n }\n\n // Filter URLs to avoid cyclic next-page loops\n return links.filter((link) => {\n if (this.handledUrls[link.url]) {\n return false;\n }\n this.handledUrls[link.url] = true;\n return true;\n });\n } catch {\n // No next URLs may be available, for example when we've reached the end of a Hydra next-page sequence.\n return [];\n }\n }\n\n public async accumulateMetadata(\n accumulatedMetadata: MetadataBindings,\n appendingMetadata: MetadataBindings,\n ): Promise<MetadataBindings> {\n return <MetadataBindings> (await this.mediatorMetadataAccumulate.mediate({\n mode: 'append',\n accumulatedMetadata,\n appendingMetadata,\n context: this.context,\n })).metadata;\n }\n}\n"]}
|
|
@@ -1,24 +1,18 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { MediatorQuerySourceIdentifyHypermedia } from '@comunica/bus-query-source-identify-hypermedia';
|
|
3
|
-
import type { MediatorRdfMetadata } from '@comunica/bus-rdf-metadata';
|
|
1
|
+
import type { MediatorQuerySourceDereferenceLink } from '@comunica/bus-query-source-dereference-link';
|
|
4
2
|
import type { MediatorRdfMetadataAccumulate } from '@comunica/bus-rdf-metadata-accumulate';
|
|
5
|
-
import type { MediatorRdfMetadataExtract } from '@comunica/bus-rdf-metadata-extract';
|
|
6
3
|
import type { MediatorRdfResolveHypermediaLinks } from '@comunica/bus-rdf-resolve-hypermedia-links';
|
|
7
4
|
import type { MediatorRdfResolveHypermediaLinksQueue } from '@comunica/bus-rdf-resolve-hypermedia-links-queue';
|
|
8
|
-
import type { BindingsStream, ComunicaDataFactory, FragmentSelectorShape, IActionContext,
|
|
5
|
+
import type { BindingsStream, ComunicaDataFactory, FragmentSelectorShape, IActionContext, IQueryBindingsOptions, IQuerySource, ILink } from '@comunica/types';
|
|
6
|
+
import type { Algebra } from '@comunica/utils-algebra';
|
|
9
7
|
import type { BindingsFactory } from '@comunica/utils-bindings-factory';
|
|
10
8
|
import type * as RDF from '@rdfjs/types';
|
|
11
9
|
import type { AsyncIterator } from 'asynciterator';
|
|
12
10
|
import { LRUCache } from 'lru-cache';
|
|
13
|
-
import type { Algebra } from 'sparqlalgebrajs';
|
|
14
11
|
import type { ISourceState } from './LinkedRdfSourcesAsyncRdfIterator';
|
|
15
12
|
export declare class QuerySourceHypermedia implements IQuerySource {
|
|
16
13
|
readonly referenceValue: string;
|
|
17
|
-
readonly
|
|
18
|
-
readonly forceSourceType?: string;
|
|
19
|
-
readonly aggregateStore: boolean;
|
|
14
|
+
readonly firstLink: ILink;
|
|
20
15
|
readonly mediators: IMediatorArgs;
|
|
21
|
-
readonly logWarning: (warningMessage: string) => void;
|
|
22
16
|
readonly dataFactory: ComunicaDataFactory;
|
|
23
17
|
readonly bindingsFactory: BindingsFactory;
|
|
24
18
|
/**
|
|
@@ -27,39 +21,33 @@ export declare class QuerySourceHypermedia implements IQuerySource {
|
|
|
27
21
|
sourcesState: LRUCache<string, Promise<ISourceState>>;
|
|
28
22
|
private readonly cacheSize;
|
|
29
23
|
private readonly maxIterators;
|
|
30
|
-
|
|
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);
|
|
24
|
+
constructor(cacheSize: number, firstUrl: ILink, maxIterators: number, mediators: IMediatorArgs, dataFactory: ComunicaDataFactory, bindingsFactory: BindingsFactory);
|
|
32
25
|
getSelectorShape(context: IActionContext): Promise<FragmentSelectorShape>;
|
|
26
|
+
getFilterFactor(context: IActionContext): Promise<number>;
|
|
33
27
|
queryBindings(operation: Algebra.Operation, context: IActionContext, options?: IQueryBindingsOptions): BindingsStream;
|
|
34
28
|
queryQuads(operation: Algebra.Operation, context: IActionContext): AsyncIterator<RDF.Quad>;
|
|
35
29
|
queryBoolean(operation: Algebra.Ask, context: IActionContext): Promise<boolean>;
|
|
36
|
-
queryVoid(operation: Algebra.
|
|
30
|
+
queryVoid(operation: Algebra.Operation, context: IActionContext): Promise<void>;
|
|
37
31
|
/**
|
|
38
32
|
* Resolve a source for the given URL.
|
|
39
33
|
* @param link A source link.
|
|
40
34
|
* @param handledDatasets A hash of dataset identifiers that have already been handled.
|
|
41
35
|
* @param context The action context.
|
|
42
|
-
* @param aggregatedStore An optional aggregated store.
|
|
43
36
|
*/
|
|
44
|
-
getSource(link: ILink, handledDatasets: Record<string, boolean>, context: IActionContext
|
|
37
|
+
getSource(link: ILink, handledDatasets: Record<string, boolean>, context: IActionContext): Promise<ISourceState>;
|
|
45
38
|
/**
|
|
46
39
|
* Resolve a source for the given URL.
|
|
47
40
|
* This will first try to retrieve the source from cache.
|
|
48
41
|
* @param link A source ILink.
|
|
49
42
|
* @param handledDatasets A hash of dataset identifiers that have already been handled.
|
|
50
43
|
* @param context The action context.
|
|
51
|
-
* @param aggregatedStore An optional aggregated store.
|
|
52
44
|
*/
|
|
53
|
-
|
|
54
|
-
getAggregateStore(context: IActionContext): IAggregatedStore | undefined;
|
|
45
|
+
getSourceCached(link: ILink, handledDatasets: Record<string, boolean>, context: IActionContext): Promise<ISourceState>;
|
|
55
46
|
toString(): string;
|
|
56
47
|
}
|
|
57
48
|
export interface IMediatorArgs {
|
|
58
|
-
mediatorDereferenceRdf: MediatorDereferenceRdf;
|
|
59
|
-
mediatorMetadata: MediatorRdfMetadata;
|
|
60
|
-
mediatorMetadataExtract: MediatorRdfMetadataExtract;
|
|
61
49
|
mediatorMetadataAccumulate: MediatorRdfMetadataAccumulate;
|
|
62
|
-
|
|
50
|
+
mediatorQuerySourceDereferenceLink: MediatorQuerySourceDereferenceLink;
|
|
63
51
|
mediatorRdfResolveHypermediaLinks: MediatorRdfResolveHypermediaLinks;
|
|
64
52
|
mediatorRdfResolveHypermediaLinksQueue: MediatorRdfResolveHypermediaLinksQueue;
|
|
65
53
|
}
|
|
@@ -1,69 +1,60 @@
|
|
|
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");
|
|
6
4
|
const asynciterator_1 = require("asynciterator");
|
|
7
5
|
const lru_cache_1 = require("lru-cache");
|
|
8
|
-
const readable_stream_1 = require("readable-stream");
|
|
9
|
-
const sparqlalgebrajs_1 = require("sparqlalgebrajs");
|
|
10
6
|
const MediatedLinkedRdfSourcesAsyncRdfIterator_1 = require("./MediatedLinkedRdfSourcesAsyncRdfIterator");
|
|
11
|
-
const StreamingStoreMetadata_1 = require("./StreamingStoreMetadata");
|
|
12
7
|
class QuerySourceHypermedia {
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
referenceValue;
|
|
9
|
+
firstLink;
|
|
10
|
+
mediators;
|
|
11
|
+
dataFactory;
|
|
12
|
+
bindingsFactory;
|
|
13
|
+
/**
|
|
14
|
+
* A cache for source URLs to source states.
|
|
15
|
+
*/
|
|
16
|
+
sourcesState;
|
|
17
|
+
cacheSize;
|
|
18
|
+
maxIterators;
|
|
19
|
+
constructor(cacheSize, firstUrl, maxIterators, mediators, dataFactory, bindingsFactory) {
|
|
20
|
+
this.referenceValue = firstUrl.url;
|
|
15
21
|
this.cacheSize = cacheSize;
|
|
16
|
-
this.
|
|
17
|
-
this.forceSourceType = forceSourceType;
|
|
22
|
+
this.firstLink = firstUrl;
|
|
18
23
|
this.maxIterators = maxIterators;
|
|
19
24
|
this.mediators = mediators;
|
|
20
|
-
this.aggregateStore = aggregateStore;
|
|
21
|
-
this.emitPartialCardinalities = emitPartialCardinalities;
|
|
22
|
-
this.logWarning = logWarning;
|
|
23
25
|
this.dataFactory = dataFactory;
|
|
24
26
|
this.bindingsFactory = bindingsFactory;
|
|
25
27
|
this.sourcesState = new lru_cache_1.LRUCache({ max: this.cacheSize });
|
|
26
28
|
}
|
|
27
29
|
async getSelectorShape(context) {
|
|
28
|
-
const source = await this.getSourceCached(
|
|
30
|
+
const source = await this.getSourceCached(this.firstLink, {}, context);
|
|
29
31
|
return source.source.getSelectorShape(context);
|
|
30
32
|
}
|
|
33
|
+
async getFilterFactor(context) {
|
|
34
|
+
const source = await this.getSourceCached(this.firstLink, {}, context);
|
|
35
|
+
return source.source.getFilterFactor(context);
|
|
36
|
+
}
|
|
31
37
|
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
|
-
}
|
|
37
38
|
// Initialize the sources state on first call
|
|
38
39
|
if (this.sourcesState.size === 0) {
|
|
39
|
-
this.getSourceCached(
|
|
40
|
+
this.getSourceCached(this.firstLink, {}, context)
|
|
40
41
|
.catch(error => it.destroy(error));
|
|
41
42
|
}
|
|
42
|
-
const
|
|
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
|
-
}
|
|
43
|
+
const it = new MediatedLinkedRdfSourcesAsyncRdfIterator_1.MediatedLinkedRdfSourcesAsyncRdfIterator(operation, options, context, this.firstLink, this.maxIterators, (link, handledDatasets) => this.getSourceCached(link, handledDatasets, context), this.mediators.mediatorMetadataAccumulate, this.mediators.mediatorRdfResolveHypermediaLinks, this.mediators.mediatorRdfResolveHypermediaLinksQueue);
|
|
53
44
|
return it;
|
|
54
45
|
}
|
|
55
46
|
queryQuads(operation, context) {
|
|
56
47
|
return new asynciterator_1.TransformIterator(async () => {
|
|
57
|
-
const source = await this.getSourceCached(
|
|
48
|
+
const source = await this.getSourceCached(this.firstLink, {}, context);
|
|
58
49
|
return source.source.queryQuads(operation, context);
|
|
59
50
|
});
|
|
60
51
|
}
|
|
61
52
|
async queryBoolean(operation, context) {
|
|
62
|
-
const source = await this.getSourceCached(
|
|
53
|
+
const source = await this.getSourceCached(this.firstLink, {}, context);
|
|
63
54
|
return await source.source.queryBoolean(operation, context);
|
|
64
55
|
}
|
|
65
56
|
async queryVoid(operation, context) {
|
|
66
|
-
const source = await this.getSourceCached(
|
|
57
|
+
const source = await this.getSourceCached(this.firstLink, {}, context);
|
|
67
58
|
return await source.source.queryVoid(operation, context);
|
|
68
59
|
}
|
|
69
60
|
/**
|
|
@@ -71,84 +62,14 @@ class QuerySourceHypermedia {
|
|
|
71
62
|
* @param link A source link.
|
|
72
63
|
* @param handledDatasets A hash of dataset identifiers that have already been handled.
|
|
73
64
|
* @param context The action context.
|
|
74
|
-
* @param aggregatedStore An optional aggregated store.
|
|
75
65
|
*/
|
|
76
|
-
async getSource(link, handledDatasets, context
|
|
77
|
-
|
|
78
|
-
|
|
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({
|
|
138
|
-
context,
|
|
139
|
-
forceSourceType: link.url === this.firstUrl ? this.forceSourceType : undefined,
|
|
66
|
+
async getSource(link, handledDatasets, context) {
|
|
67
|
+
const { source, metadata, cachePolicy } = await this.mediators.mediatorQuerySourceDereferenceLink.mediate({
|
|
68
|
+
link,
|
|
140
69
|
handledDatasets,
|
|
141
|
-
|
|
142
|
-
quads,
|
|
143
|
-
url,
|
|
70
|
+
context,
|
|
144
71
|
});
|
|
145
|
-
|
|
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 };
|
|
72
|
+
return { link, source, metadata, handledDatasets, cachePolicy };
|
|
152
73
|
}
|
|
153
74
|
/**
|
|
154
75
|
* Resolve a source for the given URL.
|
|
@@ -156,41 +77,31 @@ class QuerySourceHypermedia {
|
|
|
156
77
|
* @param link A source ILink.
|
|
157
78
|
* @param handledDatasets A hash of dataset identifiers that have already been handled.
|
|
158
79
|
* @param context The action context.
|
|
159
|
-
* @param aggregatedStore An optional aggregated store.
|
|
160
80
|
*/
|
|
161
|
-
getSourceCached(link, handledDatasets, context
|
|
81
|
+
getSourceCached(link, handledDatasets, context) {
|
|
162
82
|
let source = this.sourcesState.get(link.url);
|
|
163
83
|
if (source) {
|
|
164
|
-
return
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
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);
|
|
84
|
+
return (async () => {
|
|
85
|
+
// Check if cache policy is still valid
|
|
86
|
+
const sourceMaterialized = await source;
|
|
87
|
+
if (sourceMaterialized.cachePolicy &&
|
|
88
|
+
!await sourceMaterialized.cachePolicy?.satisfiesWithoutRevalidation({ link, context })) {
|
|
89
|
+
// If it's not valid, delete cache entry, and re-fetch immediately
|
|
90
|
+
// LIMITATION: we're not sending re-validation requests. So if the server sends a 304, we will perform a new
|
|
91
|
+
// request and re-index the source. If an HTTP-level cache is active, the actual HTTP request will not be
|
|
92
|
+
// sent, so only local re-indexing will happen, which is negligible in most cases.
|
|
93
|
+
this.sourcesState.delete(link.url);
|
|
94
|
+
return this.getSourceCached(link, handledDatasets, context);
|
|
187
95
|
}
|
|
188
|
-
return
|
|
189
|
-
}
|
|
96
|
+
return sourceMaterialized;
|
|
97
|
+
})();
|
|
190
98
|
}
|
|
99
|
+
source = this.getSource(link, handledDatasets, context);
|
|
100
|
+
this.sourcesState.set(link.url, source);
|
|
101
|
+
return source;
|
|
191
102
|
}
|
|
192
103
|
toString() {
|
|
193
|
-
return `QuerySourceHypermedia(${this.
|
|
104
|
+
return `QuerySourceHypermedia(${this.firstLink.url})`;
|
|
194
105
|
}
|
|
195
106
|
}
|
|
196
107
|
exports.QuerySourceHypermedia = QuerySourceHypermedia;
|
|
@@ -1 +1 @@
|
|
|
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"]}
|
|
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, cachePolicy } = await this.mediators.mediatorQuerySourceDereferenceLink.mediate({\n link,\n handledDatasets,\n context,\n });\n\n return { link, source, metadata, handledDatasets, cachePolicy };\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 public 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 (async() => {\n // Check if cache policy is still valid\n const sourceMaterialized = await source;\n if (sourceMaterialized.cachePolicy &&\n !await sourceMaterialized.cachePolicy?.satisfiesWithoutRevalidation({ link, context })) {\n // If it's not valid, delete cache entry, and re-fetch immediately\n // LIMITATION: we're not sending re-validation requests. So if the server sends a 304, we will perform a new\n // request and re-index the source. If an HTTP-level cache is active, the actual HTTP request will not be\n // sent, so only local re-indexing will happen, which is negligible in most cases.\n this.sourcesState.delete(link.url);\n return this.getSourceCached(link, handledDatasets, context);\n }\n return sourceMaterialized;\n })();\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"]}
|
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
|