@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.
package/.rollup/index.cjs CHANGED
@@ -213,7 +213,7 @@ function throwIfNullOrUndefined(source, errorProducer = () => new Error(`Unexpec
213
213
  return ifNullOrUndefined(source, () => { throw errorProducer(); });
214
214
  }
215
215
 
216
- class Optional {
216
+ class OptionalClz {
217
217
  _present;
218
218
  _value;
219
219
  constructor(t) {
@@ -225,9 +225,9 @@ class Optional {
225
225
  return this._value;
226
226
  }
227
227
  get() {
228
- return this.getOrElseThrow(() => new ErrorGetEmptyOptional());
228
+ return this.getOrElseThrow();
229
229
  }
230
- getOrElseThrow(errorProducer) {
230
+ getOrElseThrow(errorProducer = () => new ErrorGetEmptyOptional()) {
231
231
  if (this.isEmpty())
232
232
  throw errorProducer();
233
233
  return this._value;
@@ -262,12 +262,6 @@ class Optional {
262
262
  if (this.isPresent())
263
263
  return callback(this.get());
264
264
  }
265
- ifPresentThenClear(callback) {
266
- if (this.isPresent()) {
267
- callback(this.get());
268
- this.clear();
269
- }
270
- }
271
265
  apply(callbackIfPresent, callbackIfEmpty) {
272
266
  if (this.isEmpty()) {
273
267
  return callbackIfEmpty();
@@ -284,7 +278,6 @@ class Optional {
284
278
  return newValue;
285
279
  }
286
280
  }
287
- orElse = this.orElseReturn.bind(this);
288
281
  orElseReturnNull() {
289
282
  return this.isPresent() ? this.get() : null;
290
283
  }
@@ -299,7 +292,6 @@ class Optional {
299
292
  return newValueProducer();
300
293
  }
301
294
  }
302
- orElseGet = this.orElseProduce.bind(this);
303
295
  orElseReturnAndApply(newValue) {
304
296
  if (this.isPresent()) {
305
297
  return this.get();
@@ -340,18 +332,16 @@ class Optional {
340
332
  }
341
333
  orElseReturnNullable(newValue) {
342
334
  if (this.isEmpty())
343
- return Optional.ofNullable(newValue);
335
+ return OptionalClz.ofNullable(newValue);
344
336
  return this;
345
337
  }
346
- orElseNullable = this.orElseReturnNullable.bind(this);
347
338
  orElseProduceNullable(newValueProducer) {
348
339
  if (this.isEmpty()) {
349
340
  const newValue = newValueProducer();
350
- return Optional.ofNullable(newValue);
341
+ return OptionalClz.ofNullable(newValue);
351
342
  }
352
343
  return this;
353
344
  }
354
- orElseGetNullable = this.orElseProduceNullable.bind(this);
355
345
  orElseThrow(errorProducer) {
356
346
  if (this.isEmpty())
357
347
  throw errorProducer();
@@ -363,35 +353,35 @@ class Optional {
363
353
  throw errorProducer(this.get());
364
354
  }
365
355
  mapTo(mapper) {
366
- return this.apply(() => Optional.ofNullable(mapper(this.get())), () => Optional.empty());
356
+ return this.apply(() => OptionalClz.ofNullable(mapper(this.get())), () => OptionalClz.empty());
367
357
  }
368
358
  flatMapTo(mapper) {
369
- return this.apply(() => mapper(this.get()), () => Optional.empty());
359
+ return this.apply(() => mapper(this.get()), () => OptionalClz.empty());
370
360
  }
371
361
  filter(predicate) {
372
362
  if (this.isEmpty())
373
363
  return this;
374
364
  if (predicate(this.get()))
375
365
  return this;
376
- return Optional.empty();
366
+ return OptionalClz.empty();
377
367
  }
378
368
  static empty() {
379
- return new Optional(undefined);
369
+ return new OptionalClz(undefined);
380
370
  }
381
371
  static of(t) {
382
372
  if (isNullOrUndefined(t))
383
373
  throw new ErrorCannotInstantiatePresentOptionalWithEmptyValue();
384
- return new Optional(t);
374
+ return new OptionalClz(t);
385
375
  }
386
376
  static ofNullable(t) {
387
- return new Optional(t);
377
+ return new OptionalClz(t);
388
378
  }
389
379
  static findInArray(arr, predicate) {
390
- return Optional.ofNullable(arr.find(predicate));
380
+ return OptionalClz.ofNullable(arr.find(predicate));
391
381
  }
392
382
  static findIndexInArray(arr, predicate) {
393
383
  const idx = arr.findIndex(predicate);
394
- return idx === -1 ? Optional.empty() : Optional.of(idx);
384
+ return idx === -1 ? OptionalClz.empty() : OptionalClz.of(idx);
395
385
  }
396
386
  }
397
387
  class ErrorGetEmptyOptional extends Error {
@@ -840,11 +830,11 @@ function shallowArrayEquals(a, b) {
840
830
  }
841
831
  /** @deprecated[2026.03.01]: Use {@link Optional.findInArray} instead. */
842
832
  function findInArray(arr, predicate) {
843
- return Optional.findInArray(arr, predicate);
833
+ return OptionalClz.findInArray(arr, predicate);
844
834
  }
845
835
  /** @deprecated[2026.03.01]: Use {@link Optional.findIndexInArray} instead. */
846
836
  function findIndexInArray(arr, predicate) {
847
- return Optional.findIndexInArray(arr, predicate);
837
+ return OptionalClz.findIndexInArray(arr, predicate);
848
838
  }
849
839
  function zip(ts, rs) {
850
840
  if (ts.length !== rs.length)
@@ -865,8 +855,8 @@ function unzip(arr) {
865
855
  */
866
856
  function arrayGet(arr, index) {
867
857
  if (index < 0 || index >= arr.length)
868
- return Optional.empty();
869
- return Optional.of(arr[index]);
858
+ return OptionalClz.empty();
859
+ return OptionalClz.of(arr[index]);
870
860
  }
871
861
 
872
862
  function isTrue(x) {
@@ -1445,7 +1435,7 @@ const NEVER = new Promise(_resolve => { });
1445
1435
 
1446
1436
  /**
1447
1437
  * Returns a random integer in the range [min, max].
1448
- * @deprecated Use randomIntegerInInterval or randomDecimalInInterval instead
1438
+ * @deprecated[2026.03.17]: Use randomIntegerInInterval or randomDecimalInInterval instead.
1449
1439
  */
1450
1440
  function randomNumberInInterval(min, max) {
1451
1441
  return Math.floor(Math.random() * (max - min + 1) + min);
@@ -1500,8 +1490,6 @@ function entriesToDict(entries) {
1500
1490
  function entriesToEntries(dict, mapper) {
1501
1491
  return entriesToDict(dictToEntries(dict).map((entry) => mapper(entry)));
1502
1492
  }
1503
- /** @deprecated[2025.08.01]: Compatibility layer. */
1504
- const mapEntries = entriesToEntries;
1505
1493
  function entriesToList(dict, mapper) {
1506
1494
  return dictToEntries(dict).map((entry) => mapper(entry));
1507
1495
  }
@@ -1587,6 +1575,9 @@ class Lazy {
1587
1575
  fnEmpty();
1588
1576
  }
1589
1577
  }
1578
+ mapOrElse(onPresent, onEmpty) {
1579
+ return this._initialized ? onPresent(this._value) : onEmpty();
1580
+ }
1590
1581
  empty() {
1591
1582
  this._initialized = false;
1592
1583
  }
@@ -2504,7 +2495,7 @@ class TimeInstant extends TimeBase {
2504
2495
  });
2505
2496
  }
2506
2497
  /**
2507
- * @deprecated [2025.10.19]: Use fromIso8601 instead.
2498
+ * @deprecated[2025.10.19]: Use fromIso8601 instead.
2508
2499
  */
2509
2500
  static tryFromIso8601 = this.fromIso8601;
2510
2501
  static now() {
@@ -3799,6 +3790,49 @@ const VERSION_FIELD = "$version";
3799
3790
  * finding the shortest upgrade path and applying transformations. This is particularly useful for
3800
3791
  * handling persisted data that may be in any historical format.
3801
3792
  *
3793
+ * ## Architectural Conventions
3794
+ *
3795
+ * ### Type Aliasing
3796
+ * ```typescript
3797
+ * // Xstar = union of ALL known versions (upgrader input type)
3798
+ * type TMyData_Vstar = TMyData_V1 | TMyData_V2 | TMyData_V3;
3799
+ *
3800
+ * // No suffix = alias for the CURRENT latest version (upgrader output type)
3801
+ * type TMyData = TMyData_V3;
3802
+ * // When adding V4 later, update Vstar and change the alias:
3803
+ * // type TMyData_Vstar = TMyData_V1 | TMyData_V2 | TMyData_V3 | TMyData_V4;
3804
+ * // type TMyData = TMyData_V4;
3805
+ * ```
3806
+ *
3807
+ * ### Always Run the Upgrader
3808
+ *
3809
+ * **Every piece of serialized data must be treated as potentially any old version.**
3810
+ *
3811
+ * Never inspect `$version` manually and skip the upgrader. Always feed raw parsed data
3812
+ * directly into `upgrade()`. The upgrader is **idempotent** — calling it on data already
3813
+ * at the latest version is a no-op that returns immediately. Bypassing it creates fragile
3814
+ * fast paths that break when new versions are introduced.
3815
+ *
3816
+ * ```typescript
3817
+ * // ✅ CORRECT — always delegate to the upgrader
3818
+ * const raw = JSON.parse(json) as TMyData_Vstar;
3819
+ * const current = await upgrader.upgrade(raw);
3820
+ *
3821
+ * // ❌ WRONG — manual version check bypasses the upgrader
3822
+ * const raw = JSON.parse(json);
3823
+ * if (raw.$version === 3) {
3824
+ * // This works today, breaks silently when V4 is added
3825
+ * }
3826
+ * ```
3827
+ *
3828
+ * ### Adding a New Version
3829
+ *
3830
+ * 1. Define the new version type with `$version: N`
3831
+ * 2. Add it to the `Vstar` union
3832
+ * 3. Change the no-suffix alias to point to the new version
3833
+ * 4. Add a transition from the previous latest to the new version
3834
+ * 5. Existing code that calls `upgrade()` requires zero changes
3835
+ *
3802
3836
  * **Key Use Case:** Reading serialized data of unknown version and migrating it transparently.
3803
3837
  *
3804
3838
  * @example
@@ -3808,9 +3842,9 @@ const VERSION_FIELD = "$version";
3808
3842
  * type TSerializedData_V2 = { name: string; age: number; $version: 2 };
3809
3843
  * type TSerializedData_V3 = { name: string; age: number; email: string; $version: 3 };
3810
3844
  *
3811
- * // Step 2: Create union type and current version type
3845
+ * // Step 2: Create Vstar union (all versions) and current-version alias (latest only)
3812
3846
  * type TSerializedData_Vstar = TSerializedData_V1 | TSerializedData_V2 | TSerializedData_V3;
3813
- * type TSerializedData = TSerializedData_V3;
3847
+ * type TSerializedData = TSerializedData_V3; // Update this when adding V4
3814
3848
  *
3815
3849
  * // Step 3: Create upgrader with transition functions
3816
3850
  * const upgrader = DataUpgrader.create<TSerializedData_Vstar, TSerializedData>(3)
@@ -3950,6 +3984,13 @@ function isUpgradable(obj) {
3950
3984
  * - Duplicate transition definitions
3951
3985
  * - Backward transitions (e.g., version 2 → 1)
3952
3986
  *
3987
+ * ## Architectural Convention
3988
+ *
3989
+ * The built DataUpgrader is the **single point of versioning** for your data. Never bypass it
3990
+ * with manual `$version` checks — `upgrade()` is idempotent (no-op on latest version) and
3991
+ * accepts the full `Vstar` union, returning the current latest version. See {@link DataUpgrader}
3992
+ * for the full type aliasing conventions (`Vstar` union, no-suffix alias, adding new versions).
3993
+ *
3953
3994
  * @example
3954
3995
  * ```typescript
3955
3996
  * // Step 1: Define all historical versions with $version discriminator
@@ -4074,7 +4115,7 @@ exports.NEVER = NEVER;
4074
4115
  exports.NonExhaustiveSwitchError = NonExhaustiveSwitchError;
4075
4116
  exports.Operation = Operation;
4076
4117
  exports.OperationAggregateError = OperationAggregateError;
4077
- exports.Optional = Optional;
4118
+ exports.Optional = OptionalClz;
4078
4119
  exports.PredicateBuilder = PredicateBuilder;
4079
4120
  exports.RandomTimeDuration = RandomTimeDuration;
4080
4121
  exports.RateThrottler = RateThrottler;
@@ -4187,7 +4228,6 @@ exports.jsonCloneDeep = jsonCloneDeep;
4187
4228
  exports.last = last$1;
4188
4229
  exports.listToDict = listToDict;
4189
4230
  exports.mapDefined = mapDefined;
4190
- exports.mapEntries = mapEntries;
4191
4231
  exports.mapFirstTruthy = mapFirstTruthy;
4192
4232
  exports.mapTruthys = mapTruthys;
4193
4233
  exports.max = max;