UNPKG

@socketsecurity/lib

Version:

Core utilities and infrastructure for Socket.dev security tools

213 lines (212 loc) 6.33 kB
"use strict"; /* Socket Lib - Built with esbuild */ var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var memoization_exports = {}; __export(memoization_exports, { Memoize: () => Memoize, clearAllMemoizationCaches: () => clearAllMemoizationCaches, memoize: () => memoize, memoizeAsync: () => memoizeAsync, memoizeDebounced: () => memoizeDebounced, memoizeWeak: () => memoizeWeak, once: () => once }); module.exports = __toCommonJS(memoization_exports); var import_debug = require("./debug"); function memoize(fn, options = {}) { const { keyGen = (...args) => JSON.stringify(args), maxSize = Number.POSITIVE_INFINITY, name = fn.name || "anonymous", ttl = Number.POSITIVE_INFINITY } = options; const cache = /* @__PURE__ */ new Map(); const accessOrder = []; function evictLRU() { if (cache.size >= maxSize && accessOrder.length > 0) { const oldest = accessOrder.shift(); if (oldest) { cache.delete(oldest); (0, import_debug.debugLog)(`[memoize:${name}] clear`, { key: oldest, reason: "LRU" }); } } } function isExpired(entry) { if (ttl === Number.POSITIVE_INFINITY) { return false; } return Date.now() - entry.timestamp > ttl; } return function memoized(...args) { const key = keyGen(...args); const cached = cache.get(key); if (cached && !isExpired(cached)) { cached.hits++; const index = accessOrder.indexOf(key); if (index !== -1) { accessOrder.splice(index, 1); } accessOrder.push(key); (0, import_debug.debugLog)(`[memoize:${name}] hit`, { key, hits: cached.hits }); return cached.value; } (0, import_debug.debugLog)(`[memoize:${name}] miss`, { key }); const value = fn(...args); evictLRU(); cache.set(key, { value, timestamp: Date.now(), hits: 0 }); accessOrder.push(key); (0, import_debug.debugLog)(`[memoize:${name}] set`, { key, cacheSize: cache.size }); return value; }; } function memoizeAsync(fn, options = {}) { const { keyGen = (...args) => JSON.stringify(args), maxSize = Number.POSITIVE_INFINITY, name = fn.name || "anonymous", ttl = Number.POSITIVE_INFINITY } = options; const cache = /* @__PURE__ */ new Map(); const accessOrder = []; function evictLRU() { if (cache.size >= maxSize && accessOrder.length > 0) { const oldest = accessOrder.shift(); if (oldest) { cache.delete(oldest); (0, import_debug.debugLog)(`[memoizeAsync:${name}] clear`, { key: oldest, reason: "LRU" }); } } } function isExpired(entry) { if (ttl === Number.POSITIVE_INFINITY) { return false; } return Date.now() - entry.timestamp > ttl; } return async function memoized(...args) { const key = keyGen(...args); const cached = cache.get(key); if (cached && !isExpired(cached)) { cached.hits++; const index = accessOrder.indexOf(key); if (index !== -1) { accessOrder.splice(index, 1); } accessOrder.push(key); (0, import_debug.debugLog)(`[memoizeAsync:${name}] hit`, { key, hits: cached.hits }); return await cached.value; } (0, import_debug.debugLog)(`[memoizeAsync:${name}] miss`, { key }); const promise = fn(...args); evictLRU(); cache.set(key, { value: promise, timestamp: Date.now(), hits: 0 }); accessOrder.push(key); (0, import_debug.debugLog)(`[memoizeAsync:${name}] set`, { key, cacheSize: cache.size }); try { const result = await promise; return result; } catch (e) { cache.delete(key); const orderIndex = accessOrder.indexOf(key); if (orderIndex !== -1) { accessOrder.splice(orderIndex, 1); } (0, import_debug.debugLog)(`[memoizeAsync:${name}] clear`, { key, reason: "error" }); throw e; } }; } function Memoize(options = {}) { return (_target, propertyKey, descriptor) => { const originalMethod = descriptor.value; descriptor.value = memoize(originalMethod, { ...options, name: options.name || propertyKey }); return descriptor; }; } function clearAllMemoizationCaches() { (0, import_debug.debugLog)("[memoize:all] clear", { action: "clear-all-caches" }); } function memoizeWeak(fn) { const cache = /* @__PURE__ */ new WeakMap(); return function memoized(key) { const cached = cache.get(key); if (cached !== void 0) { (0, import_debug.debugLog)(`[memoizeWeak:${fn.name}] hit`); return cached; } (0, import_debug.debugLog)(`[memoizeWeak:${fn.name}] miss`); const result = fn(key); cache.set(key, result); return result; }; } function once(fn) { let called = false; let result; return function memoized() { if (!called) { result = fn(); called = true; (0, import_debug.debugLog)(`[once:${fn.name}] set`); } else { (0, import_debug.debugLog)(`[once:${fn.name}] hit`); } return result; }; } function memoizeDebounced(fn, wait, options = {}) { const memoized = memoize(fn, options); let timeoutId; return function debounced(...args) { if (timeoutId) { clearTimeout(timeoutId); } timeoutId = setTimeout(() => { memoized(...args); }, wait); return memoized(...args); }; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { Memoize, clearAllMemoizationCaches, memoize, memoizeAsync, memoizeDebounced, memoizeWeak, once });