UNPKG

@comunica/actor-query-source-identify-hypermedia

Version:

A hypermedia query-source-identify actor

108 lines 5.04 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.QuerySourceHypermedia = void 0; const asynciterator_1 = require("asynciterator"); const lru_cache_1 = require("lru-cache"); const MediatedLinkedRdfSourcesAsyncRdfIterator_1 = require("./MediatedLinkedRdfSourcesAsyncRdfIterator"); class QuerySourceHypermedia { referenceValue; firstLink; mediators; dataFactory; bindingsFactory; /** * A cache for source URLs to source states. */ sourcesState; cacheSize; maxIterators; constructor(cacheSize, firstUrl, maxIterators, mediators, dataFactory, bindingsFactory) { this.referenceValue = firstUrl.url; this.cacheSize = cacheSize; this.firstLink = firstUrl; this.maxIterators = maxIterators; this.mediators = mediators; this.dataFactory = dataFactory; this.bindingsFactory = bindingsFactory; this.sourcesState = new lru_cache_1.LRUCache({ max: this.cacheSize }); } async getSelectorShape(context) { const source = await this.getSourceCached(this.firstLink, {}, context); return source.source.getSelectorShape(context); } async getFilterFactor(context) { const source = await this.getSourceCached(this.firstLink, {}, context); return source.source.getFilterFactor(context); } queryBindings(operation, context, options) { // Initialize the sources state on first call if (this.sourcesState.size === 0) { this.getSourceCached(this.firstLink, {}, context) .catch(error => it.destroy(error)); } 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); return it; } queryQuads(operation, context) { return new asynciterator_1.TransformIterator(async () => { const source = await this.getSourceCached(this.firstLink, {}, context); return source.source.queryQuads(operation, context); }, { autoStart: false }); } async queryBoolean(operation, context) { const source = await this.getSourceCached(this.firstLink, {}, context); return await source.source.queryBoolean(operation, context); } async queryVoid(operation, context) { const source = await this.getSourceCached(this.firstLink, {}, context); return await source.source.queryVoid(operation, context); } /** * Resolve a source for the given URL. * @param link A source link. * @param handledDatasets A hash of dataset identifiers that have already been handled. * @param context The action context. */ async getSource(link, handledDatasets, context) { const { source, metadata, cachePolicy } = await this.mediators.mediatorQuerySourceDereferenceLink.mediate({ link, handledDatasets, context, }); return { link, source, metadata, handledDatasets, cachePolicy }; } /** * Resolve a source for the given URL. * This will first try to retrieve the source from cache. * @param link A source ILink. * @param handledDatasets A hash of dataset identifiers that have already been handled. * @param context The action context. */ getSourceCached(link, handledDatasets, context) { let source = this.sourcesState.get(link.url); if (source) { return (async () => { // Check if cache policy is still valid const sourceMaterialized = await source; if (sourceMaterialized.cachePolicy && !await sourceMaterialized.cachePolicy?.satisfiesWithoutRevalidation({ link, context })) { // If it's not valid, delete cache entry, and re-fetch immediately // LIMITATION: we're not sending re-validation requests. So if the server sends a 304, we will perform a new // request and re-index the source. If an HTTP-level cache is active, the actual HTTP request will not be // sent, so only local re-indexing will happen, which is negligible in most cases. this.sourcesState.delete(link.url); return this.getSourceCached(link, handledDatasets, context); } return sourceMaterialized; })(); } source = this.getSource(link, handledDatasets, context); this.sourcesState.set(link.url, source); return source; } toString() { return `QuerySourceHypermedia(${this.firstLink.url})`; } } exports.QuerySourceHypermedia = QuerySourceHypermedia; //# sourceMappingURL=QuerySourceHypermedia.js.map