@zelgadis87/utils-core 5.5.0-beta.2 → 6.0.0-beta.5

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.
@@ -97,12 +97,13 @@ declare function pipedInvoke<T, A, B, C, D, E, F, G, H, I>(op1: TFunction<T, A>,
97
97
  declare function pipedInvoke<T, A, B, C, D, E, F, G, H, I>(op1: TFunction<T, A>, op2: TFunction<A, B>, op3: TFunction<B, C>, op4: TFunction<C, D>, op5: TFunction<D, E>, op6: TFunction<E, F>, op7: TFunction<F, G>, op8: TFunction<G, H>, op9: TFunction<H, I>, ...operations: TFunction<any, any>[]): TFunction<T, unknown>;
98
98
  declare function pipedInvokeFromArray<T, R>(fns: Array<TFunction<any, any>>): TFunction<any, any>;
99
99
 
100
- declare class Optional<T> implements TOptional<T> {
100
+ declare class OptionalClz<T> implements TOptional<T> {
101
101
  private _present;
102
102
  private _value;
103
103
  private constructor();
104
104
  getRawValue(): T | undefined;
105
105
  get(): T;
106
+ getOrElseThrow(): T;
106
107
  getOrElseThrow(errorProducer: TProducer<Error>): T;
107
108
  set(t: T): void;
108
109
  protected setNullable(t: T | null | undefined): void | this;
@@ -111,22 +112,17 @@ declare class Optional<T> implements TOptional<T> {
111
112
  isPresent(): this is TPresentOptional<T>;
112
113
  ifEmpty(callback: TVoidFunction): void;
113
114
  ifPresent(callback: TConsumer<T>): void;
114
- ifPresentThenClear(callback: TConsumer<T>): void;
115
115
  apply(callbackIfPresent: TConsumer<T>, callbackIfEmpty: TVoidFunction): any;
116
116
  orElseReturn(newValue: T): T;
117
- orElse: (newValue: T) => T;
118
117
  orElseReturnNull(): T | null;
119
118
  orElseReturnUndefined(): T | undefined;
120
119
  orElseProduce(newValueProducer: TProducer<T>): T;
121
- orElseGet: (newValueProducer: TProducer<T>) => T;
122
120
  orElseReturnAndApply(newValue: T): T;
123
121
  orElseProduceAndApply(newValueProducer: TProducer<T>): T;
124
122
  orElseReturnNullableAndApply(newValue: T | null | undefined): TOptional<T>;
125
123
  orElseProduceNullableAndApply(newValueProducer: TProducer<T | null | undefined>): TOptional<T>;
126
124
  orElseReturnNullable(newValue: T | null | undefined): any;
127
- orElseNullable: (newValue: T | null | undefined) => any;
128
125
  orElseProduceNullable(newValueProducer: TProducer<T | null | undefined>): any;
129
- orElseGetNullable: (newValueProducer: TProducer<T | null | undefined>) => any;
130
126
  orElseThrow(errorProducer: TProducer<Error>): TPresentOptional<T>;
131
127
  throwIfPresent(errorProducer: TFunction<T, Error>): any;
132
128
  mapTo<R>(mapper: TFunction<T, R | null | undefined>): any;
@@ -138,9 +134,9 @@ declare class Optional<T> implements TOptional<T> {
138
134
  static findInArray<T>(arr: ReadonlyArray<T>, predicate: TPredicate<T>): TOptional<T>;
139
135
  static findIndexInArray<T>(arr: ReadonlyArray<T>, predicate: TPredicate<T>): TOptional<number>;
140
136
  }
141
-
142
137
  type TOptional<T> = {
143
138
  /**
139
+ * @deprecated[2026.04.07]: Replace with {@link getOrElseThrow} (drop-in replacement with no arguments)
144
140
  * @returns the currently stored value, if any; throws {@link ErrorGetEmptyOptional} otherwise;
145
141
  */
146
142
  get(): T;
@@ -149,9 +145,10 @@ type TOptional<T> = {
149
145
  */
150
146
  getRawValue(): T | undefined;
151
147
  /**
152
- * @returns the currently stored value, if any; throws the error generated by errorProducer otherwise;
148
+ * @returns the currently stored value, if any; throws {@link ErrorGetEmptyOptional} if no errorProducer is provided, or the error generated by errorProducer otherwise;
153
149
  */
154
- getOrElseThrow: (errorProducer: TProducer<Error>) => T;
150
+ getOrElseThrow(): T;
151
+ getOrElseThrow(errorProducer: TProducer<Error>): T;
155
152
  /**
156
153
  * Places a new value inside this optional. Throws {@link ErrorSetEmptyOptional} if t is null or undefined.
157
154
  */
@@ -166,15 +163,9 @@ type TOptional<T> = {
166
163
  ifPresent(callback: TConsumer<T>): void;
167
164
  apply<RP = void, RE = void>(callbackIfPresent: TFunction<T, RP>, callbackIfEmpty: TProducer<RE>): RP | RE;
168
165
  throwIfPresent: (errorGenerator: TFunction<T, Error>) => TEmptyOptional<T>;
169
- /** @deprecated[2025.07.25]: Replace with {@link orElseReturn} (drop-in replacement) */
170
- orElse: (newValue: T) => T;
171
- /** @deprecated[2025.07.25]: Replace with {@link orElseProduce} (drop-in replacement) */
172
- orElseGet: (newValueProducer: TProducer<T>) => T;
173
- /** @deprecated[2025.07.25]: Replace with {@link orElseReturnNullabe} (drop-in replacement) */
174
- orElseNullable: (newValue: T | null | undefined) => TOptional<T>;
175
- /** @deprecated[2025.07.25]: Replace with {@link orElseProduceNullable} (drop-in replacement) */
176
- orElseGetNullable: (newValueProducer: TProducer<T | null | undefined>) => TOptional<T>;
177
166
  orElseReturn: (newValue: T) => T;
167
+ orElseReturnNull(): T | null;
168
+ orElseReturnUndefined(): T | undefined;
178
169
  orElseProduce: (newValueProducer: TProducer<T>) => T;
179
170
  orElseReturnNullable: (newValue: T | null | undefined) => TOptional<T>;
180
171
  orElseProduceNullable: (newValueProducer: TProducer<T | null | undefined>) => TOptional<T>;
@@ -188,7 +179,10 @@ type TOptional<T> = {
188
179
  filter(predicate: TPredicate<T>): TOptional<T>;
189
180
  };
190
181
  type TEmptyOptional<T> = TOptional<T> & {
182
+ /** @deprecated[2026.04.07]: Replace with {@link getOrElseThrow} (drop-in replacement with no arguments) */
191
183
  get(): never;
184
+ getOrElseThrow(): never;
185
+ getOrElseThrow(errorProducer: TProducer<Error>): never;
192
186
  isEmpty(): true;
193
187
  isPresent(): false;
194
188
  apply<RP = void, RE = void>(callbackIfPresent: TFunction<T, RP>, callbackIfEmpty: TProducer<RE>): RE;
@@ -208,6 +202,8 @@ type TEmptyOptional<T> = TOptional<T> & {
208
202
  };
209
203
  type TPresentOptional<T> = TOptional<T> & {
210
204
  get(): T;
205
+ getOrElseThrow(): T;
206
+ getOrElseThrow(errorProducer: TProducer<Error>): T;
211
207
  isEmpty(): false;
212
208
  isPresent(): true;
213
209
  apply<RP = void, RE = void>(callbackIfPresent: TFunction<T, RP>, callbackIfEmpty: TProducer<RE>): RP;
@@ -550,7 +546,7 @@ declare class TimeInstant extends TimeBase<TimeInstant> {
550
546
  static builder(): TTimeInstantBuilder;
551
547
  static fromIso8601(str: string): TimeInstant;
552
548
  /**
553
- * @deprecated [2025.10.19]: Use fromIso8601 instead.
549
+ * @deprecated[2025.10.19]: Use fromIso8601 instead.
554
550
  */
555
551
  static tryFromIso8601: typeof TimeInstant.fromIso8601;
556
552
  static now(): TimeInstant;
@@ -694,16 +690,16 @@ type TSorterStepForNumbers<_T, Ret> = {
694
690
  }): Ret;
695
691
  };
696
692
  type TSorterStepForStrings<_T, Ret> = {
697
- /** @deprecated: Use inLexographicalOrder instead */ inLexographicalOrder(opts?: {
693
+ /** @deprecated[2025.09.29]: Use inLexicographicalOrder instead */ inLexographicalOrder(opts?: {
698
694
  nullsFirst?: boolean;
699
695
  }): Ret;
700
- /** @deprecated: Use inLexographicalOrderIgnoringCase instead */ inLexographicalOrderIgnoringCase(opts?: {
696
+ /** @deprecated[2025.09.29]: Use inLexicographicalOrderIgnoringCase instead */ inLexographicalOrderIgnoringCase(opts?: {
701
697
  nullsFirst?: boolean;
702
698
  }): Ret;
703
- /** @deprecated: Use inReverseLexographicalOrder instead */ inReverseLexographicalOrder(opts?: {
699
+ /** @deprecated[2025.09.29]: Use inReverseLexicographicalOrder instead */ inReverseLexographicalOrder(opts?: {
704
700
  nullsFirst?: boolean;
705
701
  }): Ret;
706
- /** @deprecated: Use inReverseLexographicalOrderIgnoringCase instead */ inReverseLexographicalOrderIgnoringCase(opts?: {
702
+ /** @deprecated[2025.09.29]: Use inReverseLexicographicalOrderIgnoringCase instead */ inReverseLexographicalOrderIgnoringCase(opts?: {
707
703
  nullsFirst?: boolean;
708
704
  }): Ret;
709
705
  inLexicographicalOrder(opts?: {
@@ -951,8 +947,6 @@ declare function isFalse(x: unknown): x is false;
951
947
  declare function dictToEntries<V, K extends string = string>(obj: Record<K, V>): [K, V][];
952
948
  declare function entriesToDict<V, K extends string = string>(entries: [K, V][]): Record<K, V>;
953
949
  declare function entriesToEntries<K1 extends string, V1, K2 extends string, V2>(dict: Record<K1, V1>, mapper: TFunction<[K1, V1], [K2, V2]>): Record<K2, V2>;
954
- /** @deprecated[2025.08.01]: Compatibility layer. */
955
- declare const mapEntries: typeof entriesToEntries;
956
950
  declare function entriesToList<K1 extends string, V1, R>(dict: Record<K1, V1>, mapper: TFunction<[K1, V1], R>): Array<R>;
957
951
 
958
952
  type TEmpty = Record<string, never>;
@@ -1061,7 +1055,7 @@ type TAsyncOperation<T, E = Error> = Promise<TOperation<T, E>>;
1061
1055
  type TOperationTuple<T, E = Error> = [T, undefined] | [undefined, E];
1062
1056
  type TAsyncOperationTuple<T, E = Error> = Promise<TOperationTuple<T, E>>;
1063
1057
  /**
1064
- * @deprecated Use `TOperation<T, OperationAggregateError<E>>` with `Operation.combine` instead.
1058
+ * @deprecated[2026.03.20]: Use `TOperation<T, OperationAggregateError<E>>` with `Operation.combine` instead.
1065
1059
  */
1066
1060
  type TValidation<T, E = Error> = {
1067
1061
  success: false;
@@ -1071,7 +1065,7 @@ type TValidation<T, E = Error> = {
1071
1065
  data: T;
1072
1066
  };
1073
1067
  /**
1074
- * @deprecated Use `TAsyncOperation<T, OperationAggregateError<E>>` with `Operation.combine` instead.
1068
+ * @deprecated[2026.03.20]: Use `TAsyncOperation<T, OperationAggregateError<E>>` with `Operation.combine` instead.
1075
1069
  */
1076
1070
  type TAsyncValidation<T, E = Error> = Promise<TValidation<T, E>>;
1077
1071
  /**
@@ -1267,7 +1261,7 @@ declare const NEVER: Promise<unknown>;
1267
1261
 
1268
1262
  /**
1269
1263
  * Returns a random integer in the range [min, max].
1270
- * @deprecated Use randomIntegerInInterval or randomDecimalInInterval instead
1264
+ * @deprecated[2026.03.17]: Use randomIntegerInInterval or randomDecimalInInterval instead.
1271
1265
  */
1272
1266
  declare function randomNumberInInterval(min: number, max: number): number;
1273
1267
  /**
@@ -1408,6 +1402,7 @@ declare class Lazy<T> {
1408
1402
  ifPresent(fn: (t: T) => void): void;
1409
1403
  ifEmpty(fn: () => void): void;
1410
1404
  apply(fnPresent: (t: T) => void, fnEmpty: () => void): void;
1405
+ mapOrElse<R>(onPresent: (t: T) => R, onEmpty: () => R): R;
1411
1406
  protected empty(): void;
1412
1407
  static of<T>(generator: () => T): Lazy<T>;
1413
1408
  }
@@ -1676,6 +1671,13 @@ type TAddTransition<T extends readonly TTransitionRecord[], From extends number,
1676
1671
  * - Duplicate transition definitions
1677
1672
  * - Backward transitions (e.g., version 2 → 1)
1678
1673
  *
1674
+ * ## Architectural Convention
1675
+ *
1676
+ * The built DataUpgrader is the **single point of versioning** for your data. Never bypass it
1677
+ * with manual `$version` checks — `upgrade()` is idempotent (no-op on latest version) and
1678
+ * accepts the full `Vstar` union, returning the current latest version. See {@link DataUpgrader}
1679
+ * for the full type aliasing conventions (`Vstar` union, no-suffix alias, adding new versions).
1680
+ *
1679
1681
  * @example
1680
1682
  * ```typescript
1681
1683
  * // Step 1: Define all historical versions with $version discriminator
@@ -1778,6 +1780,49 @@ interface IDataUpgrader<XStar extends TUpgradable, XLatest extends XStar> {
1778
1780
  * finding the shortest upgrade path and applying transformations. This is particularly useful for
1779
1781
  * handling persisted data that may be in any historical format.
1780
1782
  *
1783
+ * ## Architectural Conventions
1784
+ *
1785
+ * ### Type Aliasing
1786
+ * ```typescript
1787
+ * // Xstar = union of ALL known versions (upgrader input type)
1788
+ * type TMyData_Vstar = TMyData_V1 | TMyData_V2 | TMyData_V3;
1789
+ *
1790
+ * // No suffix = alias for the CURRENT latest version (upgrader output type)
1791
+ * type TMyData = TMyData_V3;
1792
+ * // When adding V4 later, update Vstar and change the alias:
1793
+ * // type TMyData_Vstar = TMyData_V1 | TMyData_V2 | TMyData_V3 | TMyData_V4;
1794
+ * // type TMyData = TMyData_V4;
1795
+ * ```
1796
+ *
1797
+ * ### Always Run the Upgrader
1798
+ *
1799
+ * **Every piece of serialized data must be treated as potentially any old version.**
1800
+ *
1801
+ * Never inspect `$version` manually and skip the upgrader. Always feed raw parsed data
1802
+ * directly into `upgrade()`. The upgrader is **idempotent** — calling it on data already
1803
+ * at the latest version is a no-op that returns immediately. Bypassing it creates fragile
1804
+ * fast paths that break when new versions are introduced.
1805
+ *
1806
+ * ```typescript
1807
+ * // ✅ CORRECT — always delegate to the upgrader
1808
+ * const raw = JSON.parse(json) as TMyData_Vstar;
1809
+ * const current = await upgrader.upgrade(raw);
1810
+ *
1811
+ * // ❌ WRONG — manual version check bypasses the upgrader
1812
+ * const raw = JSON.parse(json);
1813
+ * if (raw.$version === 3) {
1814
+ * // This works today, breaks silently when V4 is added
1815
+ * }
1816
+ * ```
1817
+ *
1818
+ * ### Adding a New Version
1819
+ *
1820
+ * 1. Define the new version type with `$version: N`
1821
+ * 2. Add it to the `Vstar` union
1822
+ * 3. Change the no-suffix alias to point to the new version
1823
+ * 4. Add a transition from the previous latest to the new version
1824
+ * 5. Existing code that calls `upgrade()` requires zero changes
1825
+ *
1781
1826
  * **Key Use Case:** Reading serialized data of unknown version and migrating it transparently.
1782
1827
  *
1783
1828
  * @example
@@ -1787,9 +1832,9 @@ interface IDataUpgrader<XStar extends TUpgradable, XLatest extends XStar> {
1787
1832
  * type TSerializedData_V2 = { name: string; age: number; $version: 2 };
1788
1833
  * type TSerializedData_V3 = { name: string; age: number; email: string; $version: 3 };
1789
1834
  *
1790
- * // Step 2: Create union type and current version type
1835
+ * // Step 2: Create Vstar union (all versions) and current-version alias (latest only)
1791
1836
  * type TSerializedData_Vstar = TSerializedData_V1 | TSerializedData_V2 | TSerializedData_V3;
1792
- * type TSerializedData = TSerializedData_V3;
1837
+ * type TSerializedData = TSerializedData_V3; // Update this when adding V4
1793
1838
  *
1794
1839
  * // Step 3: Create upgrader with transition functions
1795
1840
  * const upgrader = DataUpgrader.create<TSerializedData_Vstar, TSerializedData>(3)
@@ -1849,5 +1894,5 @@ declare class DataUpgrader<X extends TUpgradable, XLatest extends X> implements
1849
1894
  }
1850
1895
  declare function isUpgradable(obj: TJsonSerializable): obj is TUpgradable;
1851
1896
 
1852
- export { Cached, DataUpgrader, DataUpgraderBuilder, Deferred, DeferredCanceledError, ErrorCannotInstantiatePresentOptionalWithEmptyValue, ErrorGetEmptyOptional, ErrorSetEmptyOptional, Lazy, LazyAsync, LazyDictionary, Logger, NEVER, NonExhaustiveSwitchError, Operation, OperationAggregateError, Optional, PredicateBuilder, RandomTimeDuration, RateThrottler, Semaphore, Sorter, StringParts, TimeDuration, TimeFrequency, TimeInstant, TimeRange, TimeUnit, TimeoutError, alwaysFalse, alwaysTrue, and, arrayGet, arrayIncludes, asError, asPromise, average, averageBy, 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, fillWith, filterMap, filterMapReduce, filterWithTypePredicate, findInArray, findIndexInArray, first, flatMapTruthys, getCauseMessageFromError, getCauseStackFromError, getMessageFromError, getStackFromError, groupByBoolean, groupByBooleanWith, groupByNumber, groupByNumberWith, groupByString, groupByStringWith, groupBySymbol, groupBySymbolWith, hashCode, havingMaxBy, havingMinBy, head, identity, ifDefined, ifNullOrUndefined, iff, includes, increment, incrementBy, indexByNumber, indexByNumberWith, indexByString, indexByStringWith, indexBySymbol, indexBySymbolWith, indexByWith, 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, parseTimeInstantBasicComponents, parseTimeInstantComponents, partition, pick, pipedInvoke, pipedInvokeFromArray, pluralize, promiseSequence, randomDecimalInInterval, randomId, randomIntegerInInterval, randomNumberInInterval, randomPick, randomPicks, 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 };
1897
+ export { Cached, DataUpgrader, DataUpgraderBuilder, Deferred, DeferredCanceledError, ErrorCannotInstantiatePresentOptionalWithEmptyValue, ErrorGetEmptyOptional, ErrorSetEmptyOptional, Lazy, LazyAsync, LazyDictionary, Logger, NEVER, NonExhaustiveSwitchError, Operation, OperationAggregateError, OptionalClz as Optional, PredicateBuilder, RandomTimeDuration, RateThrottler, Semaphore, Sorter, StringParts, TimeDuration, TimeFrequency, TimeInstant, TimeRange, TimeUnit, TimeoutError, alwaysFalse, alwaysTrue, and, arrayGet, arrayIncludes, asError, asPromise, average, averageBy, 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, fillWith, filterMap, filterMapReduce, filterWithTypePredicate, findInArray, findIndexInArray, first, flatMapTruthys, getCauseMessageFromError, getCauseStackFromError, getMessageFromError, getStackFromError, groupByBoolean, groupByBooleanWith, groupByNumber, groupByNumberWith, groupByString, groupByStringWith, groupBySymbol, groupBySymbolWith, hashCode, havingMaxBy, havingMinBy, head, identity, ifDefined, ifNullOrUndefined, iff, includes, increment, incrementBy, indexByNumber, indexByNumberWith, indexByString, indexByStringWith, indexBySymbol, indexBySymbolWith, indexByWith, isAllowedTimeDuration, isArray, isDefined, isEmpty, isError, isFalse, isFunction, isNegativeNumber, isNullOrUndefined, isNullOrUndefinedOrEmpty, isNumber, isPositiveNumber, isString, isTimeInstant, isTrue, isUpgradable, isZero, jsonCloneDeep, last, listToDict, mapDefined, mapFirstTruthy, mapTruthys, max, maxBy, min, minBy, multiplyBy, noop, not, omitFromJsonObject, or, pad, padLeft, padRight, parseJson, parseTimeInstantBasicComponents, parseTimeInstantComponents, partition, pick, pipedInvoke, pipedInvokeFromArray, pluralize, promiseSequence, randomDecimalInInterval, randomId, randomIntegerInInterval, randomNumberInInterval, randomPick, randomPicks, 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 };
1853
1898
  export type { ICancelable, ICancelablePromise, IDataUpgrader, TAccumulator, TAllKeysOptional, TAnyFunction, TArrayable, TAsyncAnyFunction, TAsyncBiConsumer, TAsyncBiFunction, TAsyncBiPredicate, TAsyncConsumer, TAsyncFunction, TAsyncOperation, TAsyncOperationTuple, TAsyncPredicate, TAsyncProducer, TAsyncValidation, TAsyncVoidFunction, TBasicTimePattern, 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, TOperationFailure, TOperationSuccess, 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
@@ -211,7 +211,7 @@ function throwIfNullOrUndefined(source, errorProducer = () => new Error(`Unexpec
211
211
  return ifNullOrUndefined(source, () => { throw errorProducer(); });
212
212
  }
213
213
 
214
- class Optional {
214
+ class OptionalClz {
215
215
  _present;
216
216
  _value;
217
217
  constructor(t) {
@@ -223,9 +223,9 @@ class Optional {
223
223
  return this._value;
224
224
  }
225
225
  get() {
226
- return this.getOrElseThrow(() => new ErrorGetEmptyOptional());
226
+ return this.getOrElseThrow();
227
227
  }
228
- getOrElseThrow(errorProducer) {
228
+ getOrElseThrow(errorProducer = () => new ErrorGetEmptyOptional()) {
229
229
  if (this.isEmpty())
230
230
  throw errorProducer();
231
231
  return this._value;
@@ -260,12 +260,6 @@ class Optional {
260
260
  if (this.isPresent())
261
261
  return callback(this.get());
262
262
  }
263
- ifPresentThenClear(callback) {
264
- if (this.isPresent()) {
265
- callback(this.get());
266
- this.clear();
267
- }
268
- }
269
263
  apply(callbackIfPresent, callbackIfEmpty) {
270
264
  if (this.isEmpty()) {
271
265
  return callbackIfEmpty();
@@ -282,7 +276,6 @@ class Optional {
282
276
  return newValue;
283
277
  }
284
278
  }
285
- orElse = this.orElseReturn.bind(this);
286
279
  orElseReturnNull() {
287
280
  return this.isPresent() ? this.get() : null;
288
281
  }
@@ -297,7 +290,6 @@ class Optional {
297
290
  return newValueProducer();
298
291
  }
299
292
  }
300
- orElseGet = this.orElseProduce.bind(this);
301
293
  orElseReturnAndApply(newValue) {
302
294
  if (this.isPresent()) {
303
295
  return this.get();
@@ -338,18 +330,16 @@ class Optional {
338
330
  }
339
331
  orElseReturnNullable(newValue) {
340
332
  if (this.isEmpty())
341
- return Optional.ofNullable(newValue);
333
+ return OptionalClz.ofNullable(newValue);
342
334
  return this;
343
335
  }
344
- orElseNullable = this.orElseReturnNullable.bind(this);
345
336
  orElseProduceNullable(newValueProducer) {
346
337
  if (this.isEmpty()) {
347
338
  const newValue = newValueProducer();
348
- return Optional.ofNullable(newValue);
339
+ return OptionalClz.ofNullable(newValue);
349
340
  }
350
341
  return this;
351
342
  }
352
- orElseGetNullable = this.orElseProduceNullable.bind(this);
353
343
  orElseThrow(errorProducer) {
354
344
  if (this.isEmpty())
355
345
  throw errorProducer();
@@ -361,35 +351,35 @@ class Optional {
361
351
  throw errorProducer(this.get());
362
352
  }
363
353
  mapTo(mapper) {
364
- return this.apply(() => Optional.ofNullable(mapper(this.get())), () => Optional.empty());
354
+ return this.apply(() => OptionalClz.ofNullable(mapper(this.get())), () => OptionalClz.empty());
365
355
  }
366
356
  flatMapTo(mapper) {
367
- return this.apply(() => mapper(this.get()), () => Optional.empty());
357
+ return this.apply(() => mapper(this.get()), () => OptionalClz.empty());
368
358
  }
369
359
  filter(predicate) {
370
360
  if (this.isEmpty())
371
361
  return this;
372
362
  if (predicate(this.get()))
373
363
  return this;
374
- return Optional.empty();
364
+ return OptionalClz.empty();
375
365
  }
376
366
  static empty() {
377
- return new Optional(undefined);
367
+ return new OptionalClz(undefined);
378
368
  }
379
369
  static of(t) {
380
370
  if (isNullOrUndefined(t))
381
371
  throw new ErrorCannotInstantiatePresentOptionalWithEmptyValue();
382
- return new Optional(t);
372
+ return new OptionalClz(t);
383
373
  }
384
374
  static ofNullable(t) {
385
- return new Optional(t);
375
+ return new OptionalClz(t);
386
376
  }
387
377
  static findInArray(arr, predicate) {
388
- return Optional.ofNullable(arr.find(predicate));
378
+ return OptionalClz.ofNullable(arr.find(predicate));
389
379
  }
390
380
  static findIndexInArray(arr, predicate) {
391
381
  const idx = arr.findIndex(predicate);
392
- return idx === -1 ? Optional.empty() : Optional.of(idx);
382
+ return idx === -1 ? OptionalClz.empty() : OptionalClz.of(idx);
393
383
  }
394
384
  }
395
385
  class ErrorGetEmptyOptional extends Error {
@@ -838,11 +828,11 @@ function shallowArrayEquals(a, b) {
838
828
  }
839
829
  /** @deprecated[2026.03.01]: Use {@link Optional.findInArray} instead. */
840
830
  function findInArray(arr, predicate) {
841
- return Optional.findInArray(arr, predicate);
831
+ return OptionalClz.findInArray(arr, predicate);
842
832
  }
843
833
  /** @deprecated[2026.03.01]: Use {@link Optional.findIndexInArray} instead. */
844
834
  function findIndexInArray(arr, predicate) {
845
- return Optional.findIndexInArray(arr, predicate);
835
+ return OptionalClz.findIndexInArray(arr, predicate);
846
836
  }
847
837
  function zip(ts, rs) {
848
838
  if (ts.length !== rs.length)
@@ -863,8 +853,8 @@ function unzip(arr) {
863
853
  */
864
854
  function arrayGet(arr, index) {
865
855
  if (index < 0 || index >= arr.length)
866
- return Optional.empty();
867
- return Optional.of(arr[index]);
856
+ return OptionalClz.empty();
857
+ return OptionalClz.of(arr[index]);
868
858
  }
869
859
 
870
860
  function isTrue(x) {
@@ -1443,7 +1433,7 @@ const NEVER = new Promise(_resolve => { });
1443
1433
 
1444
1434
  /**
1445
1435
  * Returns a random integer in the range [min, max].
1446
- * @deprecated Use randomIntegerInInterval or randomDecimalInInterval instead
1436
+ * @deprecated[2026.03.17]: Use randomIntegerInInterval or randomDecimalInInterval instead.
1447
1437
  */
1448
1438
  function randomNumberInInterval(min, max) {
1449
1439
  return Math.floor(Math.random() * (max - min + 1) + min);
@@ -1498,8 +1488,6 @@ function entriesToDict(entries) {
1498
1488
  function entriesToEntries(dict, mapper) {
1499
1489
  return entriesToDict(dictToEntries(dict).map((entry) => mapper(entry)));
1500
1490
  }
1501
- /** @deprecated[2025.08.01]: Compatibility layer. */
1502
- const mapEntries = entriesToEntries;
1503
1491
  function entriesToList(dict, mapper) {
1504
1492
  return dictToEntries(dict).map((entry) => mapper(entry));
1505
1493
  }
@@ -1585,6 +1573,9 @@ class Lazy {
1585
1573
  fnEmpty();
1586
1574
  }
1587
1575
  }
1576
+ mapOrElse(onPresent, onEmpty) {
1577
+ return this._initialized ? onPresent(this._value) : onEmpty();
1578
+ }
1588
1579
  empty() {
1589
1580
  this._initialized = false;
1590
1581
  }
@@ -2502,7 +2493,7 @@ class TimeInstant extends TimeBase {
2502
2493
  });
2503
2494
  }
2504
2495
  /**
2505
- * @deprecated [2025.10.19]: Use fromIso8601 instead.
2496
+ * @deprecated[2025.10.19]: Use fromIso8601 instead.
2506
2497
  */
2507
2498
  static tryFromIso8601 = this.fromIso8601;
2508
2499
  static now() {
@@ -3797,6 +3788,49 @@ const VERSION_FIELD = "$version";
3797
3788
  * finding the shortest upgrade path and applying transformations. This is particularly useful for
3798
3789
  * handling persisted data that may be in any historical format.
3799
3790
  *
3791
+ * ## Architectural Conventions
3792
+ *
3793
+ * ### Type Aliasing
3794
+ * ```typescript
3795
+ * // Xstar = union of ALL known versions (upgrader input type)
3796
+ * type TMyData_Vstar = TMyData_V1 | TMyData_V2 | TMyData_V3;
3797
+ *
3798
+ * // No suffix = alias for the CURRENT latest version (upgrader output type)
3799
+ * type TMyData = TMyData_V3;
3800
+ * // When adding V4 later, update Vstar and change the alias:
3801
+ * // type TMyData_Vstar = TMyData_V1 | TMyData_V2 | TMyData_V3 | TMyData_V4;
3802
+ * // type TMyData = TMyData_V4;
3803
+ * ```
3804
+ *
3805
+ * ### Always Run the Upgrader
3806
+ *
3807
+ * **Every piece of serialized data must be treated as potentially any old version.**
3808
+ *
3809
+ * Never inspect `$version` manually and skip the upgrader. Always feed raw parsed data
3810
+ * directly into `upgrade()`. The upgrader is **idempotent** — calling it on data already
3811
+ * at the latest version is a no-op that returns immediately. Bypassing it creates fragile
3812
+ * fast paths that break when new versions are introduced.
3813
+ *
3814
+ * ```typescript
3815
+ * // ✅ CORRECT — always delegate to the upgrader
3816
+ * const raw = JSON.parse(json) as TMyData_Vstar;
3817
+ * const current = await upgrader.upgrade(raw);
3818
+ *
3819
+ * // ❌ WRONG — manual version check bypasses the upgrader
3820
+ * const raw = JSON.parse(json);
3821
+ * if (raw.$version === 3) {
3822
+ * // This works today, breaks silently when V4 is added
3823
+ * }
3824
+ * ```
3825
+ *
3826
+ * ### Adding a New Version
3827
+ *
3828
+ * 1. Define the new version type with `$version: N`
3829
+ * 2. Add it to the `Vstar` union
3830
+ * 3. Change the no-suffix alias to point to the new version
3831
+ * 4. Add a transition from the previous latest to the new version
3832
+ * 5. Existing code that calls `upgrade()` requires zero changes
3833
+ *
3800
3834
  * **Key Use Case:** Reading serialized data of unknown version and migrating it transparently.
3801
3835
  *
3802
3836
  * @example
@@ -3806,9 +3840,9 @@ const VERSION_FIELD = "$version";
3806
3840
  * type TSerializedData_V2 = { name: string; age: number; $version: 2 };
3807
3841
  * type TSerializedData_V3 = { name: string; age: number; email: string; $version: 3 };
3808
3842
  *
3809
- * // Step 2: Create union type and current version type
3843
+ * // Step 2: Create Vstar union (all versions) and current-version alias (latest only)
3810
3844
  * type TSerializedData_Vstar = TSerializedData_V1 | TSerializedData_V2 | TSerializedData_V3;
3811
- * type TSerializedData = TSerializedData_V3;
3845
+ * type TSerializedData = TSerializedData_V3; // Update this when adding V4
3812
3846
  *
3813
3847
  * // Step 3: Create upgrader with transition functions
3814
3848
  * const upgrader = DataUpgrader.create<TSerializedData_Vstar, TSerializedData>(3)
@@ -3948,6 +3982,13 @@ function isUpgradable(obj) {
3948
3982
  * - Duplicate transition definitions
3949
3983
  * - Backward transitions (e.g., version 2 → 1)
3950
3984
  *
3985
+ * ## Architectural Convention
3986
+ *
3987
+ * The built DataUpgrader is the **single point of versioning** for your data. Never bypass it
3988
+ * with manual `$version` checks — `upgrade()` is idempotent (no-op on latest version) and
3989
+ * accepts the full `Vstar` union, returning the current latest version. See {@link DataUpgrader}
3990
+ * for the full type aliasing conventions (`Vstar` union, no-suffix alias, adding new versions).
3991
+ *
3951
3992
  * @example
3952
3993
  * ```typescript
3953
3994
  * // Step 1: Define all historical versions with $version discriminator
@@ -4056,5 +4097,5 @@ class DataUpgraderBuilder {
4056
4097
  }
4057
4098
  }
4058
4099
 
4059
- export { Cached, DataUpgrader, DataUpgraderBuilder, Deferred, DeferredCanceledError, ErrorCannotInstantiatePresentOptionalWithEmptyValue, ErrorGetEmptyOptional, ErrorSetEmptyOptional, Lazy, LazyAsync, LazyDictionary, Logger, NEVER, NonExhaustiveSwitchError, Operation, OperationAggregateError, Optional, PredicateBuilder, RandomTimeDuration, RateThrottler, Semaphore, Sorter, StringParts, TimeDuration, TimeFrequency, TimeInstant, TimeRange, TimeUnit, TimeoutError, alwaysFalse, alwaysTrue, and, arrayGet, arrayIncludes, asError, asPromise, average, averageBy, 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, fillWith, filterMap, filterMapReduce, filterWithTypePredicate, findInArray, findIndexInArray, first$1 as first, flatMapTruthys, getCauseMessageFromError, getCauseStackFromError, getMessageFromError, getStackFromError, groupByBoolean, groupByBooleanWith, groupByNumber, groupByNumberWith, groupByString, groupByStringWith, groupBySymbol, groupBySymbolWith, hashCode, havingMaxBy, havingMinBy, head, identity, ifDefined, ifNullOrUndefined, iff, includes, increment, incrementBy, indexByNumber, indexByNumberWith, indexByString, indexByStringWith, indexBySymbol, indexBySymbolWith, indexByWith, 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, parseTimeInstantBasicComponents, parseTimeInstantComponents, partition, pick, pipedInvoke, pipedInvokeFromArray, pluralize, promiseSequence, randomDecimalInInterval, randomId, randomIntegerInInterval, randomNumberInInterval, randomPick, randomPicks, 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 };
4100
+ export { Cached, DataUpgrader, DataUpgraderBuilder, Deferred, DeferredCanceledError, ErrorCannotInstantiatePresentOptionalWithEmptyValue, ErrorGetEmptyOptional, ErrorSetEmptyOptional, Lazy, LazyAsync, LazyDictionary, Logger, NEVER, NonExhaustiveSwitchError, Operation, OperationAggregateError, OptionalClz as Optional, PredicateBuilder, RandomTimeDuration, RateThrottler, Semaphore, Sorter, StringParts, TimeDuration, TimeFrequency, TimeInstant, TimeRange, TimeUnit, TimeoutError, alwaysFalse, alwaysTrue, and, arrayGet, arrayIncludes, asError, asPromise, average, averageBy, 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, fillWith, filterMap, filterMapReduce, filterWithTypePredicate, findInArray, findIndexInArray, first$1 as first, flatMapTruthys, getCauseMessageFromError, getCauseStackFromError, getMessageFromError, getStackFromError, groupByBoolean, groupByBooleanWith, groupByNumber, groupByNumberWith, groupByString, groupByStringWith, groupBySymbol, groupBySymbolWith, hashCode, havingMaxBy, havingMinBy, head, identity, ifDefined, ifNullOrUndefined, iff, includes, increment, incrementBy, indexByNumber, indexByNumberWith, indexByString, indexByStringWith, indexBySymbol, indexBySymbolWith, indexByWith, isAllowedTimeDuration, isArray, isDefined, isEmpty, isError, isFalse, isFunction, isNegativeNumber, isNullOrUndefined, isNullOrUndefinedOrEmpty, isNumber, isPositiveNumber, isString, isTimeInstant, isTrue, isUpgradable, isZero, jsonCloneDeep, last$1 as last, listToDict, mapDefined, mapFirstTruthy, mapTruthys, max, maxBy, min, minBy, multiplyBy, noop, not, omitFromJsonObject, or, pad, padLeft, padRight, parseJson, parseTimeInstantBasicComponents, parseTimeInstantComponents, partition, pick, pipedInvoke, pipedInvokeFromArray, pluralize, promiseSequence, randomDecimalInInterval, randomId, randomIntegerInInterval, randomNumberInInterval, randomPick, randomPicks, 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 };
4060
4101
  //# sourceMappingURL=index.mjs.map