UNPKG

with-simple-caching

Version:

A wrapper that makes it simple to add caching to any function

93 lines 6.03 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.withExtendableCachingAsync = exports.hasForInputProperty = exports.WithExtendableCachingTrigger = void 0; const type_fns_1 = require("type-fns"); const getCacheFromCacheOptionOrFromForKeyArgs_1 = require("../options/getCacheFromCacheOptionOrFromForKeyArgs"); const defaults_1 = require("../serde/defaults"); const withSimpleCachingAsync_1 = require("./withSimpleCachingAsync"); /** * enumerates the extendable methods which can trigger cache operations */ var WithExtendableCachingTrigger; (function (WithExtendableCachingTrigger) { WithExtendableCachingTrigger["EXECUTE"] = "EXECUTE"; WithExtendableCachingTrigger["INVALIDATE"] = "INVALIDATE"; WithExtendableCachingTrigger["UPDATE"] = "UPDATE"; })(WithExtendableCachingTrigger = exports.WithExtendableCachingTrigger || (exports.WithExtendableCachingTrigger = {})); /** * a simple typeguard which checks if an object has a property named `forInput` */ const hasForInputProperty = (obj) => !!obj.forInput; exports.hasForInputProperty = hasForInputProperty; /** * exposes the cache-wrapped method along with some primitives which enable extending the caching logic * * specifically * - exposes a way to `invalidate` the cache, for a given input (e.g., to support external triggers for invalidation) * - exposes a way to `update` the cache, for a given input (e.g., to support write-through caching and optimistic caching) * * relevance * - when wrapping logic to cache the user is able to specify several caching options (e.g., key serialization method, value serialization method, etc) * - in order to define their own `invalidation` and `update` methods, without this function, the user would need to access these caching options per function elsewhere * - this function makes it easy to utilize and extend cache invalidation + update commands for the wrapped logic, by managing the references to the caching options on behalf of the user */ const withExtendableCachingAsync = (logic, options) => { const execute = (0, withSimpleCachingAsync_1.withSimpleCachingAsync)(logic, options); const invalidate = (args) => __awaiter(void 0, void 0, void 0, function* () { var _a, _b; // define how to get the cache, with support for `forKey` input instead of full input const cache = (0, getCacheFromCacheOptionOrFromForKeyArgs_1.getCacheFromCacheOptionOrFromForKeyArgs)({ args, options: { cache: (0, withSimpleCachingAsync_1.getOutputCacheOptionFromCacheInput)(options.cache) }, trigger: WithExtendableCachingTrigger.INVALIDATE, }); // define the key, with support for `forKey` input instead of `forInput` const serializeKey = (_b = (_a = options.serialize) === null || _a === void 0 ? void 0 : _a.key) !== null && _b !== void 0 ? _b : defaults_1.defaultKeySerializationMethod; const key = (0, exports.hasForInputProperty)(args) ? serializeKey({ forInput: args.forInput }) : args.forKey; // set undefined into the cache for this key, to invalidate the cached value yield cache.set(key, undefined); }); const update = (args) => __awaiter(void 0, void 0, void 0, function* () { var _c, _d, _e, _f, _g, _h; // define how to get the cache, with support for `forKey` input instead of full input const cache = (0, getCacheFromCacheOptionOrFromForKeyArgs_1.getCacheFromCacheOptionOrFromForKeyArgs)({ args, options: { cache: (0, withSimpleCachingAsync_1.getOutputCacheOptionFromCacheInput)(options.cache) }, trigger: WithExtendableCachingTrigger.UPDATE, }); // define the key, with support for `forKey` input instead of `forInput` const serializeKey = (_d = (_c = options.serialize) === null || _c === void 0 ? void 0 : _c.key) !== null && _d !== void 0 ? _d : defaults_1.defaultKeySerializationMethod; const key = (0, exports.hasForInputProperty)(args) ? serializeKey({ forInput: args.forInput }) : args.forKey; // deserialize the cached value const cachedValue = yield cache.get(key); const deserializeValue = (_f = (_e = options.deserialize) === null || _e === void 0 ? void 0 : _e.value) !== null && _f !== void 0 ? _f : defaults_1.defaultValueDeserializationMethod; const deserializedCachedOutput = cachedValue !== undefined ? deserializeValue(cachedValue) : undefined; // compute the new value const newValue = (0, type_fns_1.isAFunction)(args.toValue) ? yield args.toValue({ fromCachedOutput: deserializedCachedOutput }) : yield args.toValue; // define the serialized new value const serializeValue = (_h = (_g = options.serialize) === null || _g === void 0 ? void 0 : _g.value) !== null && _h !== void 0 ? _h : defaults_1.defaultValueSerializationMethod; const serializedNewValue = serializeValue(newValue); // set the new value for this key yield cache.set(key, serializedNewValue, { expiration: options.expiration, }); }); return { execute, invalidate, update }; }; exports.withExtendableCachingAsync = withExtendableCachingAsync; //# sourceMappingURL=withExtendableCachingAsync.js.map