UNPKG

@sap-cloud-sdk/connectivity

Version:

SAP Cloud SDK for JavaScript connectivity

162 lines 6 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.Cache = void 0; exports.hashCacheKey = hashCacheKey; const crypto = __importStar(require("node:crypto")); const safe_stable_stringify_1 = require("safe-stable-stringify"); /** * Representation of a cache to transiently store objects locally for faster access. * @typeParam T - Type of the cache entries. * @internal */ class Cache { /** * Creates an instance of Cache. * @param defaultValidityTime - The default validity time in milliseconds. Use 0 for unlimited cache duration. * @param capacity - The maximum number of entries in the cache. Use Infinity for unlimited size. Items are evicted based on a least recently used (LRU) strategy. */ constructor(defaultValidityTime, capacity = Infinity) { this.defaultValidityTime = defaultValidityTime; this.capacity = capacity; this.cache = new Map(); } /** * Clear all cached items. */ clear() { this.cache.clear(); } /** * Specifies whether an entry with a given key is defined in cache. * @param key - The entry's key. * @returns A boolean value that indicates whether the entry exists in cache. */ hasKey(key) { return this.cache.has(key); } /** * Getter of cached entries. * @param key - The key of the entry to retrieve. * @returns The corresponding entry to the provided key if it is still valid, returns `undefined` otherwise. */ get(key) { if (!key) { return undefined; } const entry = this.cache.get(key); if (!entry) { return undefined; } if (isExpired(entry)) { this.cache.delete(key); return undefined; } // LRU cache: Move accessed entry to the end of the Map to mark it as recently used if (this.capacity !== Infinity) { this.cache.delete(key); this.cache.set(key, entry); } return entry?.entry; } /** * Setter of entries in cache. * @param key - The entry's key. * @param item - The entry to cache. */ set(key, item) { if (!key) { return; } if (this.cache.size >= this.capacity && this.cache.size && !this.cache.has(key)) { // Evict the least recently used (LRU) entry const lruKey = this.cache.keys().next().value; this.cache.delete(lruKey); // SAFETY: size > 0 } if (this.capacity !== Infinity && this.cache.has(key)) { // If the key already exists, delete it to update its position in the LRU order this.cache.delete(key); } const expires = item.expires ?? this.inferDefaultExpirationTime(); this.cache.set(key, { entry: item.entry, expires }); } getOrInsertComputed(key, computeFn) { const cachedEntry = this.get(key); if (cachedEntry !== undefined) { return cachedEntry; } const newEntry = computeFn(); this.set(key, newEntry); return newEntry.entry; } inferDefaultExpirationTime() { const now = new Date(); return this.defaultValidityTime ? now .setMilliseconds(now.getMilliseconds() + this.defaultValidityTime) .valueOf() : undefined; } } exports.Cache = Cache; /** * Hashes the given value to create a cache key. * @internal * @param value - The value to hash. * @returns A hash of the given value using a cryptographic hash function. */ async function hashCacheKey(value) { const stringifiedValue = (0, safe_stable_stringify_1.stringify)(value); const encodedValue = new TextEncoder().encode(stringifiedValue); const hashBuffer = await crypto.subtle.digest('SHA-256', encodedValue); // TODO: Supported in Node.js 25 and later + browsers // if ((Uint8Array.prototype as any).toHex) { // // Use toHex if supported. // return (new Uint8Array(hashBuffer) as any).toHex(); // Convert ArrayBuffer to hex string. // } // If toHex() is not supported, fall back to an alternative implementation. const hashArray = Array.from(new Uint8Array(hashBuffer)); // convert buffer to byte array const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); // convert bytes to hex string return hashHex; } function isExpired(item) { if (item.expires === undefined) { return false; } return item.expires < Date.now(); } //# sourceMappingURL=cache.js.map