Pengusir-Hama-Burung-Otomatis/tugas akhir/node_modules/lru-memoizer/lib/async.js

120 lines
4.1 KiB
JavaScript

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.asyncMemoizer = void 0;
const lru_cache_1 = require("lru-cache");
const events_1 = require("events");
const lodash_clonedeep_1 = __importDefault(require("lodash.clonedeep"));
const freeze_1 = require("./freeze");
const sync_1 = require("./sync");
function asyncMemoizer(options) {
const cache = new lru_cache_1.LRUCache(options);
const load = options.load;
const hash = options.hash;
const bypass = options.bypass;
const itemTTL = options.itemTTL;
const freeze = options.freeze;
const clone = options.clone;
const queueTTL = options.queueTTL || 1000;
const loading = new Map();
const emitter = new events_1.EventEmitter();
const memoizerMethods = Object.assign({
del,
reset: () => cache.clear(),
keys: () => [...cache.keys()],
on: emitter.on.bind(emitter),
once: emitter.once.bind(emitter)
}, options);
if (options.disable) {
return Object.assign(load, memoizerMethods);
}
function del(...args) {
const key = hash(...args);
cache.delete(key);
}
function add(key, parameters, result) {
if (freeze) {
result.forEach(freeze_1.deepFreeze);
}
if (itemTTL) {
cache.set(key, result, { ttl: itemTTL(...parameters.concat(result)) });
}
else {
cache.set(key, result);
}
}
function runCallbacks(callbacks, args) {
for (const callback of callbacks) {
// Simulate async call when returning from cache
// and yield between callback resolution
if (clone) {
setImmediate(callback, ...args.map(lodash_clonedeep_1.default));
}
else {
setImmediate(callback, ...args);
}
}
}
function emit(event, ...parameters) {
emitter.emit(event, ...parameters);
}
function memoizedFunction(...args) {
const parameters = args.slice(0, -1);
const callback = args.slice(-1).pop();
let key;
if (bypass && bypass(...parameters)) {
emit('miss', ...parameters);
return load(...args);
}
if (parameters.length === 0 && !hash) {
//the load function only receives callback.
key = '_';
}
else {
key = hash(...parameters);
}
const fromCache = cache.get(key);
if (fromCache) {
emit('hit', ...parameters);
// found, invoke callback
return runCallbacks([callback], [null].concat(fromCache));
}
const pendingLoad = loading.get(key);
if (pendingLoad && pendingLoad.expiresAt > Date.now()) {
// request already in progress, queue and return
pendingLoad.queue.push(callback);
emit('queue', ...parameters);
return;
}
emit('miss', ...parameters);
const started = Date.now();
// no pending request or not resolved before expiration
// create a new queue and invoke load
const queue = [callback];
loading.set(key, {
queue,
expiresAt: started + queueTTL
});
const loadHandler = (...args) => {
const err = args[0];
if (!err) {
add(key, parameters, args.slice(1));
}
// this can potentially delete a different queue than `queue` if
// this callback was called after expiration.
// that will only cause a new call to be performed and a new queue to be
// created
loading.delete(key);
emit('loaded', Date.now() - started, ...parameters);
runCallbacks(queue, args);
};
load(...parameters, loadHandler);
}
;
return Object.assign(memoizedFunction, memoizerMethods);
}
exports.asyncMemoizer = asyncMemoizer;
asyncMemoizer.sync = sync_1.syncMemoizer;
//# sourceMappingURL=async.js.map