All files / lib MemoryCache.js

100% Statements 68/68
88.88% Branches 16/18
100% Functions 9/9
100% Lines 68/68

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 681x 1x 1x 1x 1x 1x 1x 1x 1x 3x 3x 1x 1x 1x 1x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 7x 1x 1x 1x 7x 7x 1x 1x 1x 2x 2x 2x 2x 1x 2x 2x 1x 1x 1x 1x 1x 2x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 2x
import {getEnv, getPackageJsonContent, isSet} from "./Common.js";
import console from "node:console";
 
const DEBUG = getEnv("CACHE_DEBUG", false) === "true";
//~ public
export const cacheGetVersion = () => {
    return getPackageJson()?.version;
}
export const cacheGetProjectMetadata = key => {
    return getPackageJson()?.metadata[key];
}
export const cacheGetProjectHomepage = () => {
    return getPackageJson()?.homepage;
}
export const cacheGetProjectBugsUrl = () => {
    return getPackageJson()?.bugs?.url;
}
 
//~ private
class MemoryCache {
    /**
     * handle app instance in-memory objects
     */
}
 
MemoryCache.packageJson = null;
MemoryCache.ttlObject = [/* { key, ttl, value }, { key, ttl, value } ... */];
 
//~ packageJson
const getPackageJson = () => {
    if (MemoryCache.packageJson === null) {// cache miss
        DEBUG && console.log("cache miss:packageJson")
        MemoryCache.packageJson = getPackageJsonContent();
    }
    return MemoryCache.packageJson;
}
 
//~ ttlObject
const nowEpochSec = () => {
    const now = new Date()
    const utcMsSinceEpoch = now.getTime() + (now.getTimezoneOffset() * 60 * 1000)
    return Math.round(utcMsSinceEpoch / 1000)
}
const evictDeprecatedTtlObject = () => {
    MemoryCache.ttlObject = MemoryCache.ttlObject.filter(ttlObject => ttlObject.ttl > nowEpochSec());
}
export const cacheEvictKey = key => {
    DEBUG && console.log(`cache::cacheEvictKey ${key}`);
    MemoryCache.ttlObject = MemoryCache.ttlObject.filter(ttlObject => ttlObject.key !== key);
}
export const cacheGetTtlObject = (key, ttlSecond, objectProviderFunction) => {
    return new Promise((resolve, reject) => {
        evictDeprecatedTtlObject();
        const ttlObjects = MemoryCache.ttlObject.filter(ttlObject => ttlObject.key === key)
        if (isSet(ttlObjects) && ttlObjects.length === 1) {
            return resolve(ttlObjects[0].value);
        }
        cacheEvictKey(key);
        // DEBUG && console.log(`cache miss:getTtlObject ${key}`);
        const ttl = nowEpochSec() + ttlSecond;
        objectProviderFunction()
            .then(value => {
                MemoryCache.ttlObject.push({key, ttl, value})
                resolve(value);
            })
            .catch(reject);
    });
}