Projekt

Obecné

Profil

Stáhnout (1.89 KB) Statistiky
| Větev: | Revize:
1
'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
};
(2-2/5)