UNPKG

@dasch-swiss/dsp-js

Version:

JavaScript library that handles API requests to Knora

120 lines 4.91 kB
import { of } from "rxjs"; import { map, shareReplay, take, tap } from "rxjs"; /** * Generic cache class. * Fetches information of a specific type from Knora once and caches it. * Fetches also dependencies of a requested element (non-blocking). * Works also with multiple async requests for the same key, also if not cached yet. * * @category Internal */ var GenericCache = /** @class */ (function () { function GenericCache() { /** * Cache object: key -> value. */ this.cache = {}; } /** * Gets a specific item from the cache. * If not cached yet, the information will be retrieved from DSP-API. * * @param key the id of the item to be returned. * @param isDependency true if the item to be returned * is a dependency of another item (recursive call to this method). */ GenericCache.prototype.getItem = function (key, isDependency) { var _this = this; if (isDependency === void 0) { isDependency = false; } // If the key already exists, // return the associated Observable. if (this.cache[key] !== undefined) { return this.cache[key]; } // store the observable in the cache // the next request for the same key will immediately get the observable // also if the request has not finished yet this.cache[key] = this.requestItemFromKnora(key, isDependency).pipe( // only one item is expected take(1), // DSP-API may return several elements for the request (optimization) tap(function (items) { if (items.length === 0) throw Error("No items returned from DSP-API for ".concat(key)); // the first item is expected to be the requested item if (key !== _this.getKeyOfItem(items[0])) throw Error("First item of items returned from DSP-API is expected to be {$key}"); // save all additional items returned for this request _this.saveAdditionalItems(items.slice(1)); // request dependencies of all items _this.requestDependencies(items); }), // only write the requested item to the cache for the given key map(function (res) { return res[0]; }), // make it a `ReplaySubject` so that all subscribers // will get the latest and only emitted value // // side effects (dependency handling, optimization) will only be performed once // // failed observables will be retried upon the next subscription shareReplay({ refCount: false, bufferSize: 1 })); // return the observable immediately (sync) return this.cache[key]; }; /** * Deletes an existing entry in the cache and requests information from DSP-API. * * @param key the id of the information to be returned. * @return the item. */ GenericCache.prototype.reloadItem = function (key) { if (this.cache[key] !== undefined) delete this.cache[key]; return this.getItem(key); }; /** * Handle additional items that were resolved with a request. * * @param items dependencies that have been retrieved. */ GenericCache.prototype.saveAdditionalItems = function (items) { var _this = this; // Write all available items to the cache (only for non existing keys) // Analyze dependencies of available items. items.forEach(function (item) { // Get key of item var itemKey = _this.getKeyOfItem(item); // Only write an additional item to the cache // if there is not entry for it yet // item for `key` has already been handled if (_this.cache[itemKey] === undefined) { _this.cache[itemKey] = of(item); } }); }; /** * Requests dependencies of the items retrieved from DSP-API. * * @param items items returned from DSP-API to a request. */ GenericCache.prototype.requestDependencies = function (items) { var _this = this; items.forEach(function (item) { // get items this item depends on _this.getDependenciesOfItem(item) .filter(function (depKey) { // ignore dependencies already taken care of return Object.keys(_this.cache).indexOf(depKey) === -1; }) .forEach(function (depKey) { // Request each dependency from the cache // Dependencies will be fetched independently (non-blocking). // Subscribe because the Observable is lazy _this.getItem(depKey, true).subscribe(); }); }); }; return GenericCache; }()); export { GenericCache }; //# sourceMappingURL=GenericCache.js.map