UNPKG

@itwin/presentation-backend

Version:

Backend of iTwin.js Presentation library

162 lines 5.6 kB
"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module Core */ Object.defineProperty(exports, "__esModule", { value: true }); exports.FactoryBasedTemporaryStorage = exports.TemporaryStorage = void 0; const core_bentley_1 = require("@itwin/core-bentley"); const presentation_common_1 = require("@itwin/presentation-common"); /** * Storage for values that get removed from it after being unused (not-requested * for a specified amount of time). * * @internal */ class TemporaryStorage { _timer; _values; props; /** * Constructor. Creates the storage using supplied params. */ constructor(props) { this.props = props; this._values = new Map(); if (this.props.cleanupInterval) { this._timer = setInterval(this.disposeOutdatedValues, this.props.cleanupInterval); } } /** * Destructor. Must be called to clean up the stored values * and other resources */ [Symbol.dispose]() { if (this._timer) { clearInterval(this._timer); } if (this.props.cleanupHandler) { this._values.forEach((v, id) => { this.props.cleanupHandler(id, v.value, "dispose"); }); } this._values.clear(); this.props.onDisposedAll && this.props.onDisposedAll(); } /** * Cleans up values that are currently outdated (based * on their max and unused value lifetimes specified through [[Props]]). */ disposeOutdatedValues = () => { const now = new Date().getTime(); const valuesToDispose = []; for (const [key, entry] of this._values.entries()) { if (this.props.maxValueLifetime !== undefined) { if (this.props.maxValueLifetime === 0 || now - entry.created.getTime() > this.props.maxValueLifetime) { valuesToDispose.push(key); continue; } } if (this.props.unusedValueLifetime !== undefined) { if (this.props.unusedValueLifetime === 0 || now - entry.lastUsed.getTime() > this.props.unusedValueLifetime) { valuesToDispose.push(key); continue; } } } for (const id of valuesToDispose) { this.deleteExistingEntry(id, true); } }; deleteExistingEntry(id, isTimeout) { (0, core_bentley_1.assert)(this._values.has(id)); this.props.cleanupHandler && this.props.cleanupHandler(id, this._values.get(id).value, isTimeout ? "timeout" : "request"); this._values.delete(id); this.props.onDisposedSingle && this.props.onDisposedSingle(id); } /** * Get a value from the storage. * * **Note:** requesting a value with this method updates it's last used time. */ getValue(id) { if (this._values.has(id)) { const v = this._values.get(id); v.lastUsed = new Date(); return v.value; } return undefined; } notifyValueUsed(id) { const entry = this._values.get(id); if (entry) { entry.lastUsed = new Date(); } } /** * Adds a value into the storage. * @throws An error when trying to add a value with ID that's already stored in the storage. */ addValue(id, value) { if (this._values.has(id)) { throw new presentation_common_1.PresentationError(presentation_common_1.PresentationStatus.InvalidArgument, `A value with given ID "${id}" already exists in this storage.`); } this._values.set(id, { value, created: new Date(), lastUsed: new Date() }); } /** Deletes a value with given id. */ deleteValue(id) { if (this._values.has(id)) { this.deleteExistingEntry(id, false); } } /** * Get all values currently in this storage. * * **Note:** requesting values with this method **doesn't** * update their last used times. */ get values() { const values = new Array(); for (const v of this._values.values()) { values.push(v.value); } return values; } } exports.TemporaryStorage = TemporaryStorage; /** * Storage for values that get removed from it after being unused (not-requested * for a specified amount of time). * * @internal */ class FactoryBasedTemporaryStorage extends TemporaryStorage { props; /** * Constructor. Creates the storage using supplied params. */ constructor(props) { super(props); this.props = props; } /** * Get a value from the storage. If the value with the specified id * doesn't exist, it gets created. * * **Note:** requesting a value with this method updates it's last used time. */ getValue(id) { const existingValue = super.getValue(id); if (existingValue) { return existingValue; } const value = this.props.factory(id, () => this.notifyValueUsed(id)); this.addValue(id, value); return value; } } exports.FactoryBasedTemporaryStorage = FactoryBasedTemporaryStorage; //# sourceMappingURL=TemporaryStorage.js.map