idmp
Version:
A lightweight TypeScript library for deduplicating and caching async function calls with automatic retries, designed for idempotent network requests in React and Node.js.
161 lines (160 loc) • 3.96 kB
JavaScript
/*! idmp v0.0.0 | (c) github/haozi | MIT */
;
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
/*! idmp v3.4.4 | (c) github/haozi | MIT */
const DEFAULT_MAX_AGE = 3e3;
const _7days = 6048e5;
const noop = () => {
};
const getRange = (maxAge) => {
if (maxAge < 0) return 0;
if (maxAge > _7days) return _7days;
return maxAge;
};
const getOptions = (options) => {
const {
maxRetry = 30,
maxAge: paramMaxAge = DEFAULT_MAX_AGE,
minRetryDelay = 50,
maxRetryDelay = 5e3,
onBeforeRetry = noop,
signal
} = options || {};
const maxAge = getRange(paramMaxAge);
return {
maxRetry,
maxAge,
minRetryDelay,
maxRetryDelay,
onBeforeRetry,
f: paramMaxAge === 1 / 0,
// Infinity
signal
};
};
const UNDEFINED = void 0;
const PREFIX = "@idmp/v1/";
const getCacheKey = (globalKey) => `${PREFIX}${globalKey}`;
const initStorage = (storageType) => {
let storage;
try {
storage = window[storageType];
} catch (e) {
}
const remove = (key) => {
if (!key) return;
try {
const cacheKey = getCacheKey(key);
storage.removeItem(cacheKey);
} catch (e) {
}
};
const get = (key) => {
if (!key) return;
const cacheKey = getCacheKey(key);
let localData;
try {
localData = JSON.parse(storage.getItem(cacheKey) || "");
if (localData === UNDEFINED) return;
const { t, a: maxAge, d: data } = localData;
if (Date.now() - t > maxAge) {
remove(cacheKey);
return;
}
return data;
} catch (e) {
}
};
const set = (key, data, maxAge) => {
if (!key) return;
const cacheKey = getCacheKey(key);
try {
storage.setItem(
cacheKey,
JSON.stringify({
t: Date.now(),
// timestamp
a: maxAge,
// age (ttl)
d: data
// data
})
);
} catch (e) {
}
};
const clear = () => {
try {
for (let i = storage.length - 1; i >= 0; i--) {
const key = storage.key(i);
if (key && key.startsWith(PREFIX)) {
remove(key);
}
}
} catch (e) {
}
};
return {
get,
set,
remove,
clear
};
};
const storageIdmpWrap = (_idmp, storageType = "sessionStorage") => {
const storage = initStorage(storageType);
const newIdmp = (globalKey, promiseFunc, options) => {
const finalOptions = getOptions(options);
return _idmp(
globalKey,
() => __async(null, null, function* () {
const localData = storage.get(globalKey);
if (localData !== UNDEFINED) {
if (process.env.NODE_ENV !== "production") {
console.log(
`[idmp-plugin browser-storage debug] ${globalKey} from ${storageType}["${getCacheKey(globalKey)}"]`
);
}
return localData;
}
const memoryData = yield promiseFunc();
if (memoryData !== UNDEFINED) {
storage.set(globalKey, memoryData, finalOptions.maxAge);
}
return memoryData;
}),
options
);
};
newIdmp.flush = (globalKey) => {
_idmp.flush(globalKey);
storage.remove(globalKey);
};
newIdmp.flushAll = () => {
_idmp.flushAll();
storage.clear();
};
return newIdmp;
};
exports.default = storageIdmpWrap;
exports.getCacheKey = getCacheKey;