@sap/xssec
Version:
XS Advanced Container Security API for node.js
70 lines (59 loc) • 2.37 kB
JavaScript
class ResponseReplica {
cache; // cache containing this replica
key; // cache key of this replica
request; // callback for fetching response data
data; // last response data
lastRefresh; // UNIX timestamp of last refresh
expirationTime; // time in milliseconds that needs to pass after creation for the replica to count as expired
pendingRequest; // promise for ongoing update of response or undefined
constructor(cache, key, request) {
Object.assign(this, { cache, key, request });
this.data = null;
this.expirationTime = cache.expirationTime;
}
/**
* Returns the remaining time until expiration.
* @returns time until expiration or 0 if no data available or data expired
*/
get remainingTime() {
if (!this.hasData || this.lastRefresh == null) {
return 0;
}
const elapsedTime = Date.now() - this.lastRefresh;
return Math.max(0, this.expirationTime - elapsedTime);
}
/** Returns whether the replica already has response data. **/
hasData() {
return this.data != null;
}
/** Returns whether the replica is expired. **/
isExpired() {
return this.remainingTime <= 0;
}
/**
* Returns if the replica is considered stale given the refresh period. Stale replicas should be refreshed but may still be used before expiration.
* @param refreshPeriod time period (in ms) before expiration time in which the replica should count as stale (but not yet as expired)
* @returns true if the replica is already expired or will expire within the given refresh period.
*/
isStale(refreshPeriod) {
return this.expired || this.remainingTime <= refreshPeriod;
}
/**
* Triggers a refresh of this replica. Multiple calls will still result in only one refresh at a time.
* @param {string} correlationId
*/
refresh(correlationId) {
this.pendingRequest ??= this.#fetchResponse(correlationId);
return this.pendingRequest;
}
/** Fetches new data from the request. */
async #fetchResponse(correlationId) {
try {
this.data = await this.request(correlationId);
} finally {
this.pendingRequest = null;
}
this.lastRefresh = Date.now();
}
}
module.exports = ResponseReplica;