@itwin/presentation-backend
Version:
Backend of iTwin.js Presentation library
162 lines • 5.6 kB
JavaScript
"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