@zelgadis87/utils-core 5.3.0 → 5.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.rollup/index.cjs +196 -15
- package/.rollup/index.cjs.map +1 -1
- package/.rollup/index.d.ts +113 -7
- package/.rollup/index.mjs +196 -16
- package/.rollup/index.mjs.map +1 -1
- package/.rollup/tsconfig.tsbuildinfo +1 -1
- package/CHANGELOG.md +7 -0
- package/package.json +1 -1
- package/src/lazy/Cached.ts +216 -0
- package/src/lazy/Lazy.ts +4 -0
- package/src/lazy/LazyAsync.ts +4 -0
- package/src/lazy/_index.ts +1 -0
- package/src/utils/arrays/indexBy.ts +17 -17
package/.rollup/index.d.ts
CHANGED
|
@@ -754,12 +754,12 @@ declare function groupByNumberWith<V, K extends number>(arr: TReadableArray<V>,
|
|
|
754
754
|
declare function groupByBooleanWith<V, K extends boolean>(arr: TReadableArray<V>, getter: TFunction<V, K>): Record<"true" | "false", V[]>;
|
|
755
755
|
declare function groupBySymbolWith<V, K extends symbol>(arr: TReadableArray<V>, getter: TFunction<V, K>): Record<K, V[]>;
|
|
756
756
|
|
|
757
|
-
declare function indexByString<V, K extends TKeysOfType<V, string
|
|
758
|
-
declare function indexByNumber<V, K extends TKeysOfType<V, number
|
|
759
|
-
declare function indexBySymbol<V, K extends TKeysOfType<V, symbol
|
|
760
|
-
declare function indexByStringWith<V>(arr: V[],
|
|
761
|
-
declare function indexByNumberWith<V>(arr: V[],
|
|
762
|
-
declare function indexBySymbolWith<V>(arr: V[],
|
|
757
|
+
declare function indexByString<V, K extends TKeysOfType<V, string>, R = V>(arr: V[], field: K, valueMapper?: TFunction<V, R>): Record<V[K] & string, R>;
|
|
758
|
+
declare function indexByNumber<V, K extends TKeysOfType<V, number>, R = V>(arr: V[], field: K, valueMapper?: TFunction<V, R>): Record<V[K] & number, R>;
|
|
759
|
+
declare function indexBySymbol<V, K extends TKeysOfType<V, symbol>, R = V>(arr: V[], field: K, valueMapper?: TFunction<V, R>): Record<V[K] & symbol, R>;
|
|
760
|
+
declare function indexByStringWith<V, R = V>(arr: V[], keyGetter: TFunction<V, string>, valueMapper?: TFunction<V, R>): Record<string, R>;
|
|
761
|
+
declare function indexByNumberWith<V, R = V>(arr: V[], keyGetter: TFunction<V, number>, valueMapper?: TFunction<V, R>): Record<number, R>;
|
|
762
|
+
declare function indexBySymbolWith<V, R = V>(arr: V[], keyGetter: TFunction<V, symbol>, valueMapper?: TFunction<V, R>): Record<symbol, R>;
|
|
763
763
|
|
|
764
764
|
declare function average(arr: TReadableArray<number>): number;
|
|
765
765
|
declare function sum(arr: TReadableArray<number>): number;
|
|
@@ -1177,6 +1177,7 @@ declare class Lazy<T> {
|
|
|
1177
1177
|
ifPresent(fn: (t: T) => void): void;
|
|
1178
1178
|
ifEmpty(fn: () => void): void;
|
|
1179
1179
|
apply(fnPresent: (t: T) => void, fnEmpty: () => void): void;
|
|
1180
|
+
protected empty(): void;
|
|
1180
1181
|
static of<T>(generator: () => T): Lazy<T>;
|
|
1181
1182
|
}
|
|
1182
1183
|
|
|
@@ -1201,6 +1202,7 @@ declare class LazyAsync<T> {
|
|
|
1201
1202
|
ifResolved(fn: (t: T) => void): void;
|
|
1202
1203
|
ifError(fn: (err: Error) => void): void;
|
|
1203
1204
|
getOrThrow(errorMessage?: "Value not initialized"): Promise<T> | never;
|
|
1205
|
+
protected empty(): void;
|
|
1204
1206
|
static of<T>(generator: () => Promise<T>): LazyAsync<T>;
|
|
1205
1207
|
}
|
|
1206
1208
|
|
|
@@ -1213,6 +1215,110 @@ declare class LazyDictionary<K extends string | number | symbol, T> {
|
|
|
1213
1215
|
getOrThrow(key: K, errorMessage?: "Value not initialized"): T;
|
|
1214
1216
|
}
|
|
1215
1217
|
|
|
1218
|
+
/**
|
|
1219
|
+
* A cached value with stale-while-revalidate pattern.
|
|
1220
|
+
* On initialization, the class starts calculating the async result (isPending() === true).
|
|
1221
|
+
* When complete, the class will store the generated value (isReady() === true).
|
|
1222
|
+
* After maxStale duration, the value becomes stale and will refresh in background on next access (isStale() === true).
|
|
1223
|
+
* After maxAge has passed, the cached value is no longer used (isExpired() === true).
|
|
1224
|
+
*/
|
|
1225
|
+
declare class Cached<T> {
|
|
1226
|
+
/** Current promise for the value generation. */
|
|
1227
|
+
private _promise;
|
|
1228
|
+
/** Flag indicating if a generation is currently in progress. */
|
|
1229
|
+
private _pending;
|
|
1230
|
+
/** The last successfully generated value. */
|
|
1231
|
+
private _resolvedValue;
|
|
1232
|
+
/** Function that generates the cached value. */
|
|
1233
|
+
private _generator;
|
|
1234
|
+
/** Timestamp of the last successful value generation. */
|
|
1235
|
+
private _generatedAt;
|
|
1236
|
+
/** The duration for which value should be kept cached. After maxAge from the last generated value, this object is considered empty. */
|
|
1237
|
+
private _maxAge;
|
|
1238
|
+
/** The duration for which the value should be served from cache, even if stale. Has no effect if greater or equal to maxAge. */
|
|
1239
|
+
private _maxStale;
|
|
1240
|
+
/** Callback invoked when new data becomes available. */
|
|
1241
|
+
private _onNewDataAvailable;
|
|
1242
|
+
/** Callback invoked when generation fails. */
|
|
1243
|
+
private _onError;
|
|
1244
|
+
private constructor();
|
|
1245
|
+
/**
|
|
1246
|
+
* Gets the cached value.
|
|
1247
|
+
* Returns fresh data if available, stale data while revalidating, or triggers generation if empty/expired.
|
|
1248
|
+
* @returns Promise resolving to the cached value.
|
|
1249
|
+
*/
|
|
1250
|
+
get(): Promise<T>;
|
|
1251
|
+
/**
|
|
1252
|
+
* Generates a new value using the generator function.
|
|
1253
|
+
* Sets up promise handlers for success and error cases.
|
|
1254
|
+
* @returns The generation promise.
|
|
1255
|
+
*/
|
|
1256
|
+
private generate;
|
|
1257
|
+
/**
|
|
1258
|
+
* Checks if value has been requested at least once.
|
|
1259
|
+
* @returns True if a promise exists.
|
|
1260
|
+
*/
|
|
1261
|
+
protected isPresent(): boolean;
|
|
1262
|
+
/**
|
|
1263
|
+
* Checks value has never been requested.
|
|
1264
|
+
* @returns True if empty.
|
|
1265
|
+
*/
|
|
1266
|
+
protected isEmpty(): boolean;
|
|
1267
|
+
/**
|
|
1268
|
+
* Checks if value generation is currently in progress.
|
|
1269
|
+
* @returns True if generation is pending.
|
|
1270
|
+
*/
|
|
1271
|
+
isPending(): boolean;
|
|
1272
|
+
/**
|
|
1273
|
+
* Checks if value is stored and fresh.
|
|
1274
|
+
* @returns True if stored and fresh.
|
|
1275
|
+
*/
|
|
1276
|
+
isReady(): boolean;
|
|
1277
|
+
/**
|
|
1278
|
+
* Checks if cached value is stale (older than maxStale duration).
|
|
1279
|
+
* @returns True if value is stale.
|
|
1280
|
+
*/
|
|
1281
|
+
isStale(): boolean;
|
|
1282
|
+
/**
|
|
1283
|
+
* Checks if cached value is expired (older than maxAge duration).
|
|
1284
|
+
* @returns True if value is expired.
|
|
1285
|
+
*/
|
|
1286
|
+
isExpired(): boolean;
|
|
1287
|
+
/**
|
|
1288
|
+
* Gets the timestamp when the value was last successfully generated.
|
|
1289
|
+
* @returns The last update timestamp.
|
|
1290
|
+
*/
|
|
1291
|
+
getLastUpdated(): TimeInstant;
|
|
1292
|
+
/**
|
|
1293
|
+
* Gets the age of the cached value.
|
|
1294
|
+
* @returns The duration since the value was last generated.
|
|
1295
|
+
*/
|
|
1296
|
+
getAge(): TimeDuration;
|
|
1297
|
+
/**
|
|
1298
|
+
* Invalidates the cache by resetting the generation timestamp.
|
|
1299
|
+
* Next access will trigger fresh generation.
|
|
1300
|
+
*/
|
|
1301
|
+
invalidate(): void;
|
|
1302
|
+
/**
|
|
1303
|
+
* Sets a callback to be invoked when new data becomes available.
|
|
1304
|
+
* @param callback Function to call with the new value.
|
|
1305
|
+
*/
|
|
1306
|
+
onNewDataAvailable(callback: TConsumer<T>): void;
|
|
1307
|
+
/**
|
|
1308
|
+
* Sets a callback to be invoked when generation fails.
|
|
1309
|
+
* @param callback Function to call with the error.
|
|
1310
|
+
*/
|
|
1311
|
+
onError(callback: TConsumer<Error>): void;
|
|
1312
|
+
/**
|
|
1313
|
+
* Creates a new Cached instance.
|
|
1314
|
+
* @param generator Function that generates the value to cache.
|
|
1315
|
+
* @param maxAge Maximum duration for which cached value is considered valid.
|
|
1316
|
+
* @param maxStale Maximum duration for which stale value is served while revalidating. Defaults to maxAge.
|
|
1317
|
+
* @returns A new Cached instance.
|
|
1318
|
+
*/
|
|
1319
|
+
static of<T>(generator: () => Promise<T>, maxAge: TimeDuration, maxStale?: TimeDuration): Cached<T>;
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1216
1322
|
declare const LEVELS: readonly ["trace", "log", "debug", "info", "warn", "error"];
|
|
1217
1323
|
type TLogLevel = keyof Console & typeof LEVELS[number];
|
|
1218
1324
|
type TLoggerOpts = {
|
|
@@ -1299,5 +1405,5 @@ declare class DataUpgrader<X extends TUpgradable, XLatest extends X> implements
|
|
|
1299
1405
|
}
|
|
1300
1406
|
declare function isUpgradable(obj: TJsonSerializable): obj is TUpgradable;
|
|
1301
1407
|
|
|
1302
|
-
export { DataUpgrader, Deferred, DeferredCanceledError, ErrorCannotInstantiatePresentOptionalWithEmptyValue, ErrorGetEmptyOptional, ErrorSetEmptyOptional, Lazy, LazyAsync, LazyDictionary, Logger, NEVER, NonExhaustiveSwitchError, Operation, Optional, PredicateBuilder, RandomTimeDuration, RateThrottler, Semaphore, Sorter, StringParts, TimeDuration, TimeFrequency, TimeInstant, TimeRange, TimeUnit, TimeoutError, alwaysFalse, alwaysTrue, and, arrayGet, arrayIncludes, asError, asPromise, average, awaitAtMost, capitalizeWord, clamp, clampInt0_100, constant, constantFalse, constantNull, constantOne, constantTrue, constantUndefined, constantZero, cssDeclarationRulesDictionaryToCss, decrement, decrementBy, delayPromise, dictToEntries, dictToList, divideBy, ellipsis, ensureArray, ensureDefined, ensureNegativeNumber, ensureNonNegativeNumber, ensureNonPositiveNumber, ensurePositiveNumber, ensureReadableArray, entriesToDict, entriesToEntries, entriesToList, extendArray, extendArrayWith, fill, filterMap, filterMapReduce, filterWithTypePredicate, findInArray, findIndexInArray, first, flatMapTruthys, getCauseMessageFromError, getCauseStackFromError, getMessageFromError, getStackFromError, groupByBoolean, groupByBooleanWith, groupByNumber, groupByNumberWith, groupByString, groupByStringWith, groupBySymbol, groupBySymbolWith, hashCode, head, identity, ifDefined, ifNullOrUndefined, iff, includes, increment, incrementBy, indexByNumber, indexByNumberWith, indexByString, indexByStringWith, indexBySymbol, indexBySymbolWith, isAllowedTimeDuration, isArray, isDefined, isEmpty, isError, isFalse, isFunction, isNegativeNumber, isNullOrUndefined, isNullOrUndefinedOrEmpty, isNumber, isPositiveNumber, isString, isTimeInstant, isTrue, isUpgradable, isZero, jsonCloneDeep, last, listToDict, mapDefined, mapEntries, mapFirstTruthy, mapTruthys, max, maxBy, min, minBy, multiplyBy, noop, not, omitFromJsonObject, or, pad, padLeft, padRight, parseJson, partition, pick, pipedInvoke, pipedInvokeFromArray, pluralize, promiseSequence, randomId, randomNumberInInterval, range, repeat, reverse, round, roundAwayFromZero, roundToLower, roundToNearest, roundToUpper, roundTowardsZero, shallowArrayEquals, shallowRecordEquals, sortedArray, splitWords, stringToNumber, stringifyJson, sum, sumBy, tail, throttle, throwIfNullOrUndefined, transformCssDictionary, tryToParseJson, tryToParseNumber, uniq, uniqBy, uniqByKey, unzip, upsert, withTryCatch, withTryCatchAsync, wrapWithString, xor, zip };
|
|
1408
|
+
export { Cached, DataUpgrader, Deferred, DeferredCanceledError, ErrorCannotInstantiatePresentOptionalWithEmptyValue, ErrorGetEmptyOptional, ErrorSetEmptyOptional, Lazy, LazyAsync, LazyDictionary, Logger, NEVER, NonExhaustiveSwitchError, Operation, Optional, PredicateBuilder, RandomTimeDuration, RateThrottler, Semaphore, Sorter, StringParts, TimeDuration, TimeFrequency, TimeInstant, TimeRange, TimeUnit, TimeoutError, alwaysFalse, alwaysTrue, and, arrayGet, arrayIncludes, asError, asPromise, average, awaitAtMost, capitalizeWord, clamp, clampInt0_100, constant, constantFalse, constantNull, constantOne, constantTrue, constantUndefined, constantZero, cssDeclarationRulesDictionaryToCss, decrement, decrementBy, delayPromise, dictToEntries, dictToList, divideBy, ellipsis, ensureArray, ensureDefined, ensureNegativeNumber, ensureNonNegativeNumber, ensureNonPositiveNumber, ensurePositiveNumber, ensureReadableArray, entriesToDict, entriesToEntries, entriesToList, extendArray, extendArrayWith, fill, filterMap, filterMapReduce, filterWithTypePredicate, findInArray, findIndexInArray, first, flatMapTruthys, getCauseMessageFromError, getCauseStackFromError, getMessageFromError, getStackFromError, groupByBoolean, groupByBooleanWith, groupByNumber, groupByNumberWith, groupByString, groupByStringWith, groupBySymbol, groupBySymbolWith, hashCode, head, identity, ifDefined, ifNullOrUndefined, iff, includes, increment, incrementBy, indexByNumber, indexByNumberWith, indexByString, indexByStringWith, indexBySymbol, indexBySymbolWith, isAllowedTimeDuration, isArray, isDefined, isEmpty, isError, isFalse, isFunction, isNegativeNumber, isNullOrUndefined, isNullOrUndefinedOrEmpty, isNumber, isPositiveNumber, isString, isTimeInstant, isTrue, isUpgradable, isZero, jsonCloneDeep, last, listToDict, mapDefined, mapEntries, mapFirstTruthy, mapTruthys, max, maxBy, min, minBy, multiplyBy, noop, not, omitFromJsonObject, or, pad, padLeft, padRight, parseJson, partition, pick, pipedInvoke, pipedInvokeFromArray, pluralize, promiseSequence, randomId, randomNumberInInterval, range, repeat, reverse, round, roundAwayFromZero, roundToLower, roundToNearest, roundToUpper, roundTowardsZero, shallowArrayEquals, shallowRecordEquals, sortedArray, splitWords, stringToNumber, stringifyJson, sum, sumBy, tail, throttle, throwIfNullOrUndefined, transformCssDictionary, tryToParseJson, tryToParseNumber, uniq, uniqBy, uniqByKey, unzip, upsert, withTryCatch, withTryCatchAsync, wrapWithString, xor, zip };
|
|
1303
1409
|
export type { ICancelable, ICancelablePromise, IDataUpgrader, TAccumulator, TAllKeysOptional, TAnyFunction, TArrayable, TAsyncAnyFunction, TAsyncBiConsumer, TAsyncBiFunction, TAsyncBiPredicate, TAsyncConsumer, TAsyncFunction, TAsyncOperation, TAsyncOperationTuple, TAsyncPredicate, TAsyncProducer, TAsyncValidation, TAsyncVoidFunction, TBiConsumer, TBiFunction, TBiPredicate, TComparisonDirection, TComparisonFunction, TComparisonResult, TConditionalOptionalType, TConditionalParameter, TConditionalParameterOptions, TConsumer, TCssDeclarationRulesDictionary, TCssSelectorDeclarationRulesDictionary, TDayOfMonth, TDayOfWeek, TDigit, TDigit1_9, TEmpty, TEmptyArray, TEmptyObject, TEmptyOptional, TFourDigits, TFourDigitsMillisecond, TFourDigitsYear, TFunction, THasNever, THourOfDay, THtmlString, TIdentityFunction, TIntervalHandle, TIsEmptyObject, TIso8601DateString, TIso8601DateUtcString, TJsonArray, TJsonObject, TJsonPrimitive, TJsonSerializable, TKeysOfType, TLoggerOpts, TMaybe, TMillisecondOfSecond, TMinuteOfHour, TMonth, TMonthName, TNegativeNumber, TNumber0_10, TNumber0_100, TNumber0_1000, TNumber0_15, TNumber0_20, TNumber0_5, TNumber1_10, TNumericFloatingPointString, TNumericString, TOneDigit, TOperation, TOperationTuple, TOptional, TOptionalKeysForType, TOptionsWithoutDefaults, TParseInt, TParseableInt, TPositiveNumber, TPredefinedTimeDuration, TPredicate, TPresentOptional, TPrettify, TPrimitive, TProducer, TPromisable, TReadableArray, TRelativeUrl, TReplaceType, TRequiredKeysForType, TSecondOfMinute, TSorter, TSorterBuilder, TStrictComparisonResult, TThreeDigits, TThreeDigitsMillisecond, TTimeInUnits, TTimeoutHandle, TTransformer, TTwoDigits, TTwoDigitsDate, TTwoDigitsHour, TTwoDigitsMinute, TTwoDigitsMonth, TTwoDigitsSecond, TTypePredicate, TUpToFourDigits, TUpToThreeDigits, TUpToTwoDigits, TUpgradable, TUrl, TValidTimeDuration, TValidation, TVoidFunction, TWeekNumber, TWithExtras, TWithRequiredProperties, TWithRequiredProperty, TYear, TZero };
|
package/.rollup/index.mjs
CHANGED
|
@@ -413,32 +413,32 @@ function doGroupByWith(arr, getter) {
|
|
|
413
413
|
}, {});
|
|
414
414
|
}
|
|
415
415
|
|
|
416
|
-
function indexByString(arr, field) {
|
|
417
|
-
return indexByStringWith(arr, t => t[field]);
|
|
416
|
+
function indexByString(arr, field, valueMapper = v => v) {
|
|
417
|
+
return indexByStringWith(arr, t => t[field], valueMapper);
|
|
418
418
|
}
|
|
419
|
-
function indexByNumber(arr, field) {
|
|
420
|
-
return indexByNumberWith(arr, t => t[field]);
|
|
419
|
+
function indexByNumber(arr, field, valueMapper = v => v) {
|
|
420
|
+
return indexByNumberWith(arr, t => t[field], valueMapper);
|
|
421
421
|
}
|
|
422
|
-
function indexBySymbol(arr, field) {
|
|
423
|
-
return indexBySymbolWith(arr, t => t[field]);
|
|
422
|
+
function indexBySymbol(arr, field, valueMapper = v => v) {
|
|
423
|
+
return indexBySymbolWith(arr, t => t[field], valueMapper);
|
|
424
424
|
}
|
|
425
|
-
function indexByStringWith(arr,
|
|
426
|
-
return doIndexByWith(arr,
|
|
425
|
+
function indexByStringWith(arr, keyGetter, valueMapper = v => v) {
|
|
426
|
+
return doIndexByWith(arr, keyGetter, valueMapper);
|
|
427
427
|
}
|
|
428
|
-
function indexByNumberWith(arr,
|
|
429
|
-
return doIndexByWith(arr,
|
|
428
|
+
function indexByNumberWith(arr, keyGetter, valueMapper = v => v) {
|
|
429
|
+
return doIndexByWith(arr, keyGetter, valueMapper);
|
|
430
430
|
}
|
|
431
|
-
function indexBySymbolWith(arr,
|
|
432
|
-
return doIndexByWith(arr,
|
|
431
|
+
function indexBySymbolWith(arr, keyGetter, valueMapper = v => v) {
|
|
432
|
+
return doIndexByWith(arr, keyGetter, valueMapper);
|
|
433
433
|
}
|
|
434
|
-
function doIndexByWith(arr,
|
|
434
|
+
function doIndexByWith(arr, keyGetter, valueMapper = v => v) {
|
|
435
435
|
return arr.reduce((dict, cur) => {
|
|
436
|
-
const key =
|
|
436
|
+
const key = keyGetter(cur);
|
|
437
437
|
if (key !== null && key !== undefined) {
|
|
438
438
|
if (dict[key]) {
|
|
439
439
|
throw new Error(`Multiple values indexed by same key "${String(key)}".`);
|
|
440
440
|
}
|
|
441
|
-
dict[key] = cur;
|
|
441
|
+
dict[key] = valueMapper(cur);
|
|
442
442
|
}
|
|
443
443
|
return dict;
|
|
444
444
|
}, {});
|
|
@@ -1315,6 +1315,9 @@ class Lazy {
|
|
|
1315
1315
|
fnEmpty();
|
|
1316
1316
|
}
|
|
1317
1317
|
}
|
|
1318
|
+
empty() {
|
|
1319
|
+
this._initialized = false;
|
|
1320
|
+
}
|
|
1318
1321
|
static of(generator) {
|
|
1319
1322
|
return new Lazy(generator);
|
|
1320
1323
|
}
|
|
@@ -1396,6 +1399,9 @@ class LazyAsync {
|
|
|
1396
1399
|
throw new Error(errorMessage);
|
|
1397
1400
|
return this._promise;
|
|
1398
1401
|
}
|
|
1402
|
+
empty() {
|
|
1403
|
+
this._promise = undefined;
|
|
1404
|
+
}
|
|
1399
1405
|
static of(generator) {
|
|
1400
1406
|
return new LazyAsync(generator);
|
|
1401
1407
|
}
|
|
@@ -2610,6 +2616,180 @@ class Logger {
|
|
|
2610
2616
|
}
|
|
2611
2617
|
}
|
|
2612
2618
|
|
|
2619
|
+
const logger = new Logger('Cached');
|
|
2620
|
+
/**
|
|
2621
|
+
* A cached value with stale-while-revalidate pattern.
|
|
2622
|
+
* On initialization, the class starts calculating the async result (isPending() === true).
|
|
2623
|
+
* When complete, the class will store the generated value (isReady() === true).
|
|
2624
|
+
* After maxStale duration, the value becomes stale and will refresh in background on next access (isStale() === true).
|
|
2625
|
+
* After maxAge has passed, the cached value is no longer used (isExpired() === true).
|
|
2626
|
+
*/
|
|
2627
|
+
class Cached {
|
|
2628
|
+
/** Current promise for the value generation. */
|
|
2629
|
+
_promise = undefined;
|
|
2630
|
+
/** Flag indicating if a generation is currently in progress. */
|
|
2631
|
+
_pending = false;
|
|
2632
|
+
/** The last successfully generated value. */
|
|
2633
|
+
_resolvedValue = undefined;
|
|
2634
|
+
/** Function that generates the cached value. */
|
|
2635
|
+
_generator;
|
|
2636
|
+
/** Timestamp of the last successful value generation. */
|
|
2637
|
+
_generatedAt = TimeInstant.ZERO;
|
|
2638
|
+
/** The duration for which value should be kept cached. After maxAge from the last generated value, this object is considered empty. */
|
|
2639
|
+
_maxAge;
|
|
2640
|
+
/** The duration for which the value should be served from cache, even if stale. Has no effect if greater or equal to maxAge. */
|
|
2641
|
+
_maxStale;
|
|
2642
|
+
/** Callback invoked when new data becomes available. */
|
|
2643
|
+
_onNewDataAvailable = noop;
|
|
2644
|
+
/** Callback invoked when generation fails. */
|
|
2645
|
+
_onError = err => logger.error('Cache generation failed:', err);
|
|
2646
|
+
constructor(generator, maxAge, maxStale) {
|
|
2647
|
+
this._generator = ensureDefined(generator);
|
|
2648
|
+
this._maxAge = ensureDefined(maxAge);
|
|
2649
|
+
this._maxStale = ensureDefined(TimeDuration.lowest(maxAge, maxStale));
|
|
2650
|
+
}
|
|
2651
|
+
/**
|
|
2652
|
+
* Gets the cached value.
|
|
2653
|
+
* Returns fresh data if available, stale data while revalidating, or triggers generation if empty/expired.
|
|
2654
|
+
* @returns Promise resolving to the cached value.
|
|
2655
|
+
*/
|
|
2656
|
+
async get() {
|
|
2657
|
+
if (this.isPending()) {
|
|
2658
|
+
return this._promise;
|
|
2659
|
+
}
|
|
2660
|
+
else if (this.isEmpty() || this.isExpired()) {
|
|
2661
|
+
this._promise = this.generate();
|
|
2662
|
+
return this._promise;
|
|
2663
|
+
}
|
|
2664
|
+
else {
|
|
2665
|
+
if (this.isStale()) {
|
|
2666
|
+
// Start re-generating the contents, while serving stale data.
|
|
2667
|
+
void this.generate();
|
|
2668
|
+
}
|
|
2669
|
+
return this._resolvedValue;
|
|
2670
|
+
}
|
|
2671
|
+
}
|
|
2672
|
+
/**
|
|
2673
|
+
* Generates a new value using the generator function.
|
|
2674
|
+
* Sets up promise handlers for success and error cases.
|
|
2675
|
+
* @returns The generation promise.
|
|
2676
|
+
*/
|
|
2677
|
+
generate() {
|
|
2678
|
+
if (this._pending)
|
|
2679
|
+
return this._promise;
|
|
2680
|
+
this._pending = true;
|
|
2681
|
+
const deferred = new Deferred();
|
|
2682
|
+
this._generator().then(value => {
|
|
2683
|
+
this._pending = false;
|
|
2684
|
+
this._resolvedValue = value;
|
|
2685
|
+
this._generatedAt = TimeInstant.now();
|
|
2686
|
+
deferred.resolve(value);
|
|
2687
|
+
withTryCatch(() => this._onNewDataAvailable(value));
|
|
2688
|
+
}, error => {
|
|
2689
|
+
const err = asError(error);
|
|
2690
|
+
this._pending = false;
|
|
2691
|
+
deferred.reject(err);
|
|
2692
|
+
withTryCatch(() => this._onError(err));
|
|
2693
|
+
});
|
|
2694
|
+
return deferred.asPromise();
|
|
2695
|
+
}
|
|
2696
|
+
/**
|
|
2697
|
+
* Checks if value has been requested at least once.
|
|
2698
|
+
* @returns True if a promise exists.
|
|
2699
|
+
*/
|
|
2700
|
+
isPresent() {
|
|
2701
|
+
return this._promise !== undefined;
|
|
2702
|
+
}
|
|
2703
|
+
/**
|
|
2704
|
+
* Checks value has never been requested.
|
|
2705
|
+
* @returns True if empty.
|
|
2706
|
+
*/
|
|
2707
|
+
isEmpty() {
|
|
2708
|
+
return this._promise === undefined;
|
|
2709
|
+
}
|
|
2710
|
+
/**
|
|
2711
|
+
* Checks if value generation is currently in progress.
|
|
2712
|
+
* @returns True if generation is pending.
|
|
2713
|
+
*/
|
|
2714
|
+
isPending() {
|
|
2715
|
+
return this.isPresent() && this._pending === true;
|
|
2716
|
+
}
|
|
2717
|
+
/**
|
|
2718
|
+
* Checks if value is stored and fresh.
|
|
2719
|
+
* @returns True if stored and fresh.
|
|
2720
|
+
*/
|
|
2721
|
+
isReady() {
|
|
2722
|
+
return this.isPresent() && this.getAge().isLessThan(this._maxAge);
|
|
2723
|
+
}
|
|
2724
|
+
// protected isResolved() {
|
|
2725
|
+
// return this.isReady() && this._error === undefined;
|
|
2726
|
+
// }
|
|
2727
|
+
// protected isError() {
|
|
2728
|
+
// return this.isReady() && this._error !== undefined;
|
|
2729
|
+
// }
|
|
2730
|
+
/**
|
|
2731
|
+
* Checks if cached value is stale (older than maxStale duration).
|
|
2732
|
+
* @returns True if value is stale.
|
|
2733
|
+
*/
|
|
2734
|
+
isStale() {
|
|
2735
|
+
return this.isPresent() && this.getAge().isGreaterThan(this._maxStale);
|
|
2736
|
+
}
|
|
2737
|
+
/**
|
|
2738
|
+
* Checks if cached value is expired (older than maxAge duration).
|
|
2739
|
+
* @returns True if value is expired.
|
|
2740
|
+
*/
|
|
2741
|
+
isExpired() {
|
|
2742
|
+
return this.isPresent() && this.getAge().isGreaterThan(this._maxAge);
|
|
2743
|
+
}
|
|
2744
|
+
/**
|
|
2745
|
+
* Gets the timestamp when the value was last successfully generated.
|
|
2746
|
+
* @returns The last update timestamp.
|
|
2747
|
+
*/
|
|
2748
|
+
getLastUpdated() {
|
|
2749
|
+
return this._generatedAt;
|
|
2750
|
+
}
|
|
2751
|
+
/**
|
|
2752
|
+
* Gets the age of the cached value.
|
|
2753
|
+
* @returns The duration since the value was last generated.
|
|
2754
|
+
*/
|
|
2755
|
+
getAge() {
|
|
2756
|
+
return this._generatedAt.distanceFromNow();
|
|
2757
|
+
}
|
|
2758
|
+
/**
|
|
2759
|
+
* Invalidates the cache by resetting the generation timestamp.
|
|
2760
|
+
* Next access will trigger fresh generation.
|
|
2761
|
+
*/
|
|
2762
|
+
invalidate() {
|
|
2763
|
+
this._generatedAt = TimeInstant.ZERO;
|
|
2764
|
+
}
|
|
2765
|
+
/**
|
|
2766
|
+
* Sets a callback to be invoked when new data becomes available.
|
|
2767
|
+
* @param callback Function to call with the new value.
|
|
2768
|
+
*/
|
|
2769
|
+
onNewDataAvailable(callback) {
|
|
2770
|
+
this._onNewDataAvailable = ensureDefined(callback);
|
|
2771
|
+
}
|
|
2772
|
+
/**
|
|
2773
|
+
* Sets a callback to be invoked when generation fails.
|
|
2774
|
+
* @param callback Function to call with the error.
|
|
2775
|
+
*/
|
|
2776
|
+
onError(callback) {
|
|
2777
|
+
this._onError = ensureDefined(callback);
|
|
2778
|
+
}
|
|
2779
|
+
/**
|
|
2780
|
+
* Creates a new Cached instance.
|
|
2781
|
+
* @param generator Function that generates the value to cache.
|
|
2782
|
+
* @param maxAge Maximum duration for which cached value is considered valid.
|
|
2783
|
+
* @param maxStale Maximum duration for which stale value is served while revalidating. Defaults to maxAge.
|
|
2784
|
+
* @returns A new Cached instance.
|
|
2785
|
+
*/
|
|
2786
|
+
static of(generator, maxAge, maxStale = maxAge) {
|
|
2787
|
+
const cached = new Cached(generator, maxAge, maxStale);
|
|
2788
|
+
void cached.get();
|
|
2789
|
+
return cached;
|
|
2790
|
+
}
|
|
2791
|
+
}
|
|
2792
|
+
|
|
2613
2793
|
const defaultCompareValuesOptions = {
|
|
2614
2794
|
nullsFirst: false,
|
|
2615
2795
|
};
|
|
@@ -3084,5 +3264,5 @@ function isUpgradable(obj) {
|
|
|
3084
3264
|
return isDefined(obj) && typeof obj === "object" && VERSION_FIELD in obj && isNumber(obj.$version) && isPositiveNumber(obj.$version);
|
|
3085
3265
|
}
|
|
3086
3266
|
|
|
3087
|
-
export { DataUpgrader, Deferred, DeferredCanceledError, ErrorCannotInstantiatePresentOptionalWithEmptyValue, ErrorGetEmptyOptional, ErrorSetEmptyOptional, Lazy, LazyAsync, LazyDictionary, Logger, NEVER, NonExhaustiveSwitchError, Operation, Optional, PredicateBuilder, RandomTimeDuration, RateThrottler, Semaphore, Sorter, StringParts, TimeDuration, TimeFrequency, TimeInstant, TimeRange, TimeUnit, TimeoutError, alwaysFalse, alwaysTrue, and, arrayGet, arrayIncludes, asError, asPromise, average, awaitAtMost, capitalizeWord, clamp, clampInt0_100, constant, constantFalse, constantNull, constantOne, constantTrue, constantUndefined, constantZero, cssDeclarationRulesDictionaryToCss, decrement, decrementBy, delayPromise, dictToEntries, dictToList, divideBy, ellipsis, ensureArray, ensureDefined, ensureNegativeNumber, ensureNonNegativeNumber, ensureNonPositiveNumber, ensurePositiveNumber, ensureReadableArray, entriesToDict, entriesToEntries, entriesToList, extendArray, extendArrayWith, fill, filterMap, filterMapReduce, filterWithTypePredicate, findInArray, findIndexInArray, first$1 as first, flatMapTruthys, getCauseMessageFromError, getCauseStackFromError, getMessageFromError, getStackFromError, groupByBoolean, groupByBooleanWith, groupByNumber, groupByNumberWith, groupByString, groupByStringWith, groupBySymbol, groupBySymbolWith, hashCode, head, identity, ifDefined, ifNullOrUndefined, iff, includes, increment, incrementBy, indexByNumber, indexByNumberWith, indexByString, indexByStringWith, indexBySymbol, indexBySymbolWith, isAllowedTimeDuration, isArray, isDefined, isEmpty, isError, isFalse, isFunction, isNegativeNumber, isNullOrUndefined, isNullOrUndefinedOrEmpty, isNumber, isPositiveNumber, isString, isTimeInstant, isTrue, isUpgradable, isZero, jsonCloneDeep, last$1 as last, listToDict, mapDefined, mapEntries, mapFirstTruthy, mapTruthys, max, maxBy, min, minBy, multiplyBy, noop, not, omitFromJsonObject, or, pad, padLeft, padRight, parseJson, partition, pick, pipedInvoke, pipedInvokeFromArray, pluralize, promiseSequence, randomId, randomNumberInInterval, range, repeat, reverse$1 as reverse, round, roundAwayFromZero, roundToLower, roundToNearest, roundToUpper, roundTowardsZero, shallowArrayEquals, shallowRecordEquals, sortedArray, splitWords, stringToNumber, stringifyJson, sum, sumBy, tail, throttle, throwIfNullOrUndefined, transformCssDictionary, tryToParseJson, tryToParseNumber, uniq, uniqBy, uniqByKey, unzip, upsert, withTryCatch, withTryCatchAsync, wrapWithString, xor, zip };
|
|
3267
|
+
export { Cached, DataUpgrader, Deferred, DeferredCanceledError, ErrorCannotInstantiatePresentOptionalWithEmptyValue, ErrorGetEmptyOptional, ErrorSetEmptyOptional, Lazy, LazyAsync, LazyDictionary, Logger, NEVER, NonExhaustiveSwitchError, Operation, Optional, PredicateBuilder, RandomTimeDuration, RateThrottler, Semaphore, Sorter, StringParts, TimeDuration, TimeFrequency, TimeInstant, TimeRange, TimeUnit, TimeoutError, alwaysFalse, alwaysTrue, and, arrayGet, arrayIncludes, asError, asPromise, average, awaitAtMost, capitalizeWord, clamp, clampInt0_100, constant, constantFalse, constantNull, constantOne, constantTrue, constantUndefined, constantZero, cssDeclarationRulesDictionaryToCss, decrement, decrementBy, delayPromise, dictToEntries, dictToList, divideBy, ellipsis, ensureArray, ensureDefined, ensureNegativeNumber, ensureNonNegativeNumber, ensureNonPositiveNumber, ensurePositiveNumber, ensureReadableArray, entriesToDict, entriesToEntries, entriesToList, extendArray, extendArrayWith, fill, filterMap, filterMapReduce, filterWithTypePredicate, findInArray, findIndexInArray, first$1 as first, flatMapTruthys, getCauseMessageFromError, getCauseStackFromError, getMessageFromError, getStackFromError, groupByBoolean, groupByBooleanWith, groupByNumber, groupByNumberWith, groupByString, groupByStringWith, groupBySymbol, groupBySymbolWith, hashCode, head, identity, ifDefined, ifNullOrUndefined, iff, includes, increment, incrementBy, indexByNumber, indexByNumberWith, indexByString, indexByStringWith, indexBySymbol, indexBySymbolWith, isAllowedTimeDuration, isArray, isDefined, isEmpty, isError, isFalse, isFunction, isNegativeNumber, isNullOrUndefined, isNullOrUndefinedOrEmpty, isNumber, isPositiveNumber, isString, isTimeInstant, isTrue, isUpgradable, isZero, jsonCloneDeep, last$1 as last, listToDict, mapDefined, mapEntries, mapFirstTruthy, mapTruthys, max, maxBy, min, minBy, multiplyBy, noop, not, omitFromJsonObject, or, pad, padLeft, padRight, parseJson, partition, pick, pipedInvoke, pipedInvokeFromArray, pluralize, promiseSequence, randomId, randomNumberInInterval, range, repeat, reverse$1 as reverse, round, roundAwayFromZero, roundToLower, roundToNearest, roundToUpper, roundTowardsZero, shallowArrayEquals, shallowRecordEquals, sortedArray, splitWords, stringToNumber, stringifyJson, sum, sumBy, tail, throttle, throwIfNullOrUndefined, transformCssDictionary, tryToParseJson, tryToParseNumber, uniq, uniqBy, uniqByKey, unzip, upsert, withTryCatch, withTryCatchAsync, wrapWithString, xor, zip };
|
|
3088
3268
|
//# sourceMappingURL=index.mjs.map
|