Completed
Pull Request — master (#7)
by
unknown
01:45
created

src/index.js   A

Complexity

Total Complexity 0
Complexity/F 0

Size

Lines of Code 4
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 0
c 2
b 0
f 0
nc 1
dl 0
loc 4
rs 10
wmc 0
mnd 0
bc 0
fnc 0
bpm 0
cpm 0
noi 0
1
import UnityCacheError from './error';
2
import localforage from 'localforage/dist/localforage.nopromises';
3
4
const DB_DRIVER = [ localforage.INDEXEDDB, localforage.WEBSQL, localforage.LOCALSTORAGE ];
5
const RE_BIN = /^\w+$/;
6
const EXPIRE_BIN = '___expire___';
7
const EXPIRE_GLUE = '::';
8
const DEFAULT_NAME = 'unity';
9
const DEFAULT_DESCRIPTION = 'Unity cache';
10
11
let cacheBins = {};
12
13
function createCacheBins(bins, name, description, driver) {
14
    bins = [].concat(bins, EXPIRE_BIN);
15
16
    return bins.reduce((result, storeName) => {
17
        if (!RE_BIN.test(storeName)) {
18
            throw new UnityCacheError(`Store names can only be alphanumeric, '${storeName}' given`);
19
        }
20
21
        result[storeName] = localforage.createInstance({
22
            storeName,
23
            name,
24
            description,
25
            driver
26
        });
27
28
        return result;
29
    }, {});
30
}
31
32
function getExpireKey(bin, key) {
33
    return bin + EXPIRE_GLUE + key;
34
}
35
36
async function get(bin, key, validate = true) {
37
    const expired = await cacheBins[EXPIRE_BIN].getItem(getExpireKey(bin, key));
38
    const isValid = validate && cacheBins[bin] ? expired > Date.now() : true;
39
40
    if (!isValid) {
41
        await cacheBins[EXPIRE_BIN].removeItem(getExpireKey(bin, key));
42
    }
43
44
    return isValid ? await cacheBins[bin].getItem(key) : null; // localForage return null if item doesn't exist
45
}
46
47
async function set(bin, key, data, expire = Number.MAX_SAFE_INTEGER) {
48
    return await Promise.all([
49
        cacheBins[EXPIRE_BIN].setItem(getExpireKey(bin, key), Date.now() + Number(expire)),
50
        cacheBins[bin].setItem(key, data)
51
    ]);
52
}
53
54
async function remove(bin, key) {
55
    return await Promise.all([
56
        cacheBins[EXPIRE_BIN].removeItem(getExpireKey(bin, key)),
57
        cacheBins[bin].removeItem(key)
58
    ]);
59
}
60
61
function drop(bins) {
62
    bins = [].concat(bins);
63
    bins.map(bin => cacheBins[bin].clear());
64
}
65
66
function createCache(bins, name = DEFAULT_NAME, description = DEFAULT_DESCRIPTION, driver = DB_DRIVER) {
67
    cacheBins = createCacheBins(bins, name, description, driver);
68
69
    return {
70
        get,
71
        set,
72
        remove,
73
        drop
74
    };
75
}
76
77
export default createCache;
78