Projekt

Obecné

Profil

Stáhnout (1.89 KB) Statistiky
| Větev: | Revize:
1 3a515b92 cagy
'use strict';
2
const mimicFn = require('mimic-fn');
3
const isPromise = require('p-is-promise');
4
const mapAgeCleaner = require('map-age-cleaner');
5
6
const cacheStore = new WeakMap();
7
8
const defaultCacheKey = (...arguments_) => {
9
	if (arguments_.length === 0) {
10
		return '__defaultKey';
11
	}
12
13
	if (arguments_.length === 1) {
14
		const [firstArgument] = arguments_;
15
		if (
16
			firstArgument === null ||
17
			firstArgument === undefined ||
18
			(typeof firstArgument !== 'function' && typeof firstArgument !== 'object')
19
		) {
20
			return firstArgument;
21
		}
22
	}
23
24
	return JSON.stringify(arguments_);
25
};
26
27
const mem = (fn, options) => {
28
	options = Object.assign({
29
		cacheKey: defaultCacheKey,
30
		cache: new Map(),
31
		cachePromiseRejection: false
32
	}, options);
33
34
	if (typeof options.maxAge === 'number') {
35
		mapAgeCleaner(options.cache);
36
	}
37
38
	const {cache} = options;
39
	options.maxAge = options.maxAge || 0;
40
41
	const setData = (key, data) => {
42
		cache.set(key, {
43
			data,
44
			maxAge: Date.now() + options.maxAge
45
		});
46
	};
47
48
	const memoized = function (...arguments_) {
49
		const key = options.cacheKey(...arguments_);
50
51
		if (cache.has(key)) {
52
			return cache.get(key).data;
53
		}
54
55
		const cacheItem = fn.call(this, ...arguments_);
56
57
		setData(key, cacheItem);
58
59
		if (isPromise(cacheItem) && options.cachePromiseRejection === false) {
60
			// Remove rejected promises from cache unless `cachePromiseRejection` is set to `true`
61
			cacheItem.catch(() => cache.delete(key));
62
		}
63
64
		return cacheItem;
65
	};
66
67
	try {
68
		// The below call will throw in some host environments
69
		// See https://github.com/sindresorhus/mimic-fn/issues/10
70
		mimicFn(memoized, fn);
71
	} catch (_) {}
72
73
	cacheStore.set(memoized, options.cache);
74
75
	return memoized;
76
};
77
78
module.exports = mem;
79
// TODO: Remove this for the next major release
80
module.exports.default = mem;
81
82
module.exports.clear = fn => {
83
	const cache = cacheStore.get(fn);
84
85
	if (cache && typeof cache.clear === 'function') {
86
		cache.clear();
87
	}
88
};