@zelgadis87/utils-core 5.5.0-beta.2 → 5.5.0-beta.4
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 +58 -4
- package/.rollup/index.cjs.map +1 -1
- package/.rollup/index.d.ts +65 -4
- package/.rollup/index.mjs +58 -4
- package/.rollup/index.mjs.map +1 -1
- package/.rollup/tsconfig.tsbuildinfo +1 -1
- package/CHANGELOG.md +16 -0
- package/package.json +1 -1
- package/src/Optional.ts +15 -4
- package/src/lazy/Lazy.ts +7 -3
- package/src/upgrade/DataUpgrader.ts +45 -2
- package/src/upgrade/DataUpgraderBuilder.ts +7 -0
package/.rollup/index.cjs
CHANGED
|
@@ -224,10 +224,11 @@ class Optional {
|
|
|
224
224
|
getRawValue() {
|
|
225
225
|
return this._value;
|
|
226
226
|
}
|
|
227
|
+
/** @deprecated[2026.04.07]: Replace with {@link getOrElseThrow} (drop-in replacement with no arguments) */
|
|
227
228
|
get() {
|
|
228
|
-
return this.getOrElseThrow(
|
|
229
|
+
return this.getOrElseThrow();
|
|
229
230
|
}
|
|
230
|
-
getOrElseThrow(errorProducer) {
|
|
231
|
+
getOrElseThrow(errorProducer = () => new ErrorGetEmptyOptional()) {
|
|
231
232
|
if (this.isEmpty())
|
|
232
233
|
throw errorProducer();
|
|
233
234
|
return this._value;
|
|
@@ -1587,6 +1588,9 @@ class Lazy {
|
|
|
1587
1588
|
fnEmpty();
|
|
1588
1589
|
}
|
|
1589
1590
|
}
|
|
1591
|
+
mapOrElse(onPresent, onEmpty) {
|
|
1592
|
+
return this._initialized ? onPresent(this._value) : onEmpty();
|
|
1593
|
+
}
|
|
1590
1594
|
empty() {
|
|
1591
1595
|
this._initialized = false;
|
|
1592
1596
|
}
|
|
@@ -3799,6 +3803,49 @@ const VERSION_FIELD = "$version";
|
|
|
3799
3803
|
* finding the shortest upgrade path and applying transformations. This is particularly useful for
|
|
3800
3804
|
* handling persisted data that may be in any historical format.
|
|
3801
3805
|
*
|
|
3806
|
+
* ## Architectural Conventions
|
|
3807
|
+
*
|
|
3808
|
+
* ### Type Aliasing
|
|
3809
|
+
* ```typescript
|
|
3810
|
+
* // Xstar = union of ALL known versions (upgrader input type)
|
|
3811
|
+
* type TMyData_Vstar = TMyData_V1 | TMyData_V2 | TMyData_V3;
|
|
3812
|
+
*
|
|
3813
|
+
* // No suffix = alias for the CURRENT latest version (upgrader output type)
|
|
3814
|
+
* type TMyData = TMyData_V3;
|
|
3815
|
+
* // When adding V4 later, update Vstar and change the alias:
|
|
3816
|
+
* // type TMyData_Vstar = TMyData_V1 | TMyData_V2 | TMyData_V3 | TMyData_V4;
|
|
3817
|
+
* // type TMyData = TMyData_V4;
|
|
3818
|
+
* ```
|
|
3819
|
+
*
|
|
3820
|
+
* ### Always Run the Upgrader
|
|
3821
|
+
*
|
|
3822
|
+
* **Every piece of serialized data must be treated as potentially any old version.**
|
|
3823
|
+
*
|
|
3824
|
+
* Never inspect `$version` manually and skip the upgrader. Always feed raw parsed data
|
|
3825
|
+
* directly into `upgrade()`. The upgrader is **idempotent** — calling it on data already
|
|
3826
|
+
* at the latest version is a no-op that returns immediately. Bypassing it creates fragile
|
|
3827
|
+
* fast paths that break when new versions are introduced.
|
|
3828
|
+
*
|
|
3829
|
+
* ```typescript
|
|
3830
|
+
* // ✅ CORRECT — always delegate to the upgrader
|
|
3831
|
+
* const raw = JSON.parse(json) as TMyData_Vstar;
|
|
3832
|
+
* const current = await upgrader.upgrade(raw);
|
|
3833
|
+
*
|
|
3834
|
+
* // ❌ WRONG — manual version check bypasses the upgrader
|
|
3835
|
+
* const raw = JSON.parse(json);
|
|
3836
|
+
* if (raw.$version === 3) {
|
|
3837
|
+
* // This works today, breaks silently when V4 is added
|
|
3838
|
+
* }
|
|
3839
|
+
* ```
|
|
3840
|
+
*
|
|
3841
|
+
* ### Adding a New Version
|
|
3842
|
+
*
|
|
3843
|
+
* 1. Define the new version type with `$version: N`
|
|
3844
|
+
* 2. Add it to the `Vstar` union
|
|
3845
|
+
* 3. Change the no-suffix alias to point to the new version
|
|
3846
|
+
* 4. Add a transition from the previous latest to the new version
|
|
3847
|
+
* 5. Existing code that calls `upgrade()` requires zero changes
|
|
3848
|
+
*
|
|
3802
3849
|
* **Key Use Case:** Reading serialized data of unknown version and migrating it transparently.
|
|
3803
3850
|
*
|
|
3804
3851
|
* @example
|
|
@@ -3808,9 +3855,9 @@ const VERSION_FIELD = "$version";
|
|
|
3808
3855
|
* type TSerializedData_V2 = { name: string; age: number; $version: 2 };
|
|
3809
3856
|
* type TSerializedData_V3 = { name: string; age: number; email: string; $version: 3 };
|
|
3810
3857
|
*
|
|
3811
|
-
* // Step 2: Create union
|
|
3858
|
+
* // Step 2: Create Vstar union (all versions) and current-version alias (latest only)
|
|
3812
3859
|
* type TSerializedData_Vstar = TSerializedData_V1 | TSerializedData_V2 | TSerializedData_V3;
|
|
3813
|
-
* type TSerializedData = TSerializedData_V3;
|
|
3860
|
+
* type TSerializedData = TSerializedData_V3; // Update this when adding V4
|
|
3814
3861
|
*
|
|
3815
3862
|
* // Step 3: Create upgrader with transition functions
|
|
3816
3863
|
* const upgrader = DataUpgrader.create<TSerializedData_Vstar, TSerializedData>(3)
|
|
@@ -3950,6 +3997,13 @@ function isUpgradable(obj) {
|
|
|
3950
3997
|
* - Duplicate transition definitions
|
|
3951
3998
|
* - Backward transitions (e.g., version 2 → 1)
|
|
3952
3999
|
*
|
|
4000
|
+
* ## Architectural Convention
|
|
4001
|
+
*
|
|
4002
|
+
* The built DataUpgrader is the **single point of versioning** for your data. Never bypass it
|
|
4003
|
+
* with manual `$version` checks — `upgrade()` is idempotent (no-op on latest version) and
|
|
4004
|
+
* accepts the full `Vstar` union, returning the current latest version. See {@link DataUpgrader}
|
|
4005
|
+
* for the full type aliasing conventions (`Vstar` union, no-suffix alias, adding new versions).
|
|
4006
|
+
*
|
|
3953
4007
|
* @example
|
|
3954
4008
|
* ```typescript
|
|
3955
4009
|
* // Step 1: Define all historical versions with $version discriminator
|