@itwin/core-quantity 5.10.0-dev.9 → 5.10.0
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/CHANGELOG.md +31 -1
- package/README.md +17 -0
- package/lib/cjs/BasicUnitsProvider.d.ts +8 -5
- package/lib/cjs/BasicUnitsProvider.d.ts.map +1 -1
- package/lib/cjs/BasicUnitsProvider.js +16 -139
- package/lib/cjs/BasicUnitsProvider.js.map +1 -1
- package/lib/cjs/Exception.d.ts +2 -1
- package/lib/cjs/Exception.d.ts.map +1 -1
- package/lib/cjs/Exception.js +1 -0
- package/lib/cjs/Exception.js.map +1 -1
- package/lib/cjs/FormatSpecHandle.d.ts +1 -2
- package/lib/cjs/FormatSpecHandle.d.ts.map +1 -1
- package/lib/cjs/FormatSpecHandle.js +0 -1
- package/lib/cjs/FormatSpecHandle.js.map +1 -1
- package/lib/cjs/Quantity.d.ts +4 -0
- package/lib/cjs/Quantity.d.ts.map +1 -1
- package/lib/cjs/Quantity.js +12 -23
- package/lib/cjs/Quantity.js.map +1 -1
- package/lib/cjs/UnitConversion/UnitConversion.js +6 -6
- package/lib/cjs/UnitConversion/UnitConversion.js.map +1 -1
- package/lib/cjs/UnitConversions.d.ts +40 -0
- package/lib/cjs/UnitConversions.d.ts.map +1 -0
- package/lib/cjs/UnitConversions.js +121 -0
- package/lib/cjs/UnitConversions.js.map +1 -0
- package/lib/cjs/assets/Units.json +72 -1
- package/lib/cjs/core-quantity.d.ts +6 -0
- package/lib/cjs/core-quantity.d.ts.map +1 -1
- package/lib/cjs/core-quantity.js +6 -0
- package/lib/cjs/core-quantity.js.map +1 -1
- package/lib/cjs/generated/Units.generated.d.ts +785 -0
- package/lib/cjs/generated/Units.generated.d.ts.map +1 -0
- package/lib/cjs/generated/Units.generated.js +775 -0
- package/lib/cjs/generated/Units.generated.js.map +1 -0
- package/lib/cjs/internal/BasicUnitConversionData.d.ts +33 -0
- package/lib/cjs/internal/BasicUnitConversionData.d.ts.map +1 -0
- package/lib/cjs/internal/BasicUnitConversionData.js +126 -0
- package/lib/cjs/internal/BasicUnitConversionData.js.map +1 -0
- package/lib/cjs/internal/BasicUnitConversions.generated.d.ts +507 -0
- package/lib/cjs/internal/BasicUnitConversions.generated.d.ts.map +1 -0
- package/lib/cjs/internal/BasicUnitConversions.generated.js +515 -0
- package/lib/cjs/internal/BasicUnitConversions.generated.js.map +1 -0
- package/lib/cjs/internal/BasicUnitsResolvedStateCache.d.ts +12 -0
- package/lib/cjs/internal/BasicUnitsResolvedStateCache.d.ts.map +1 -0
- package/lib/cjs/internal/BasicUnitsResolvedStateCache.js +37 -0
- package/lib/cjs/internal/BasicUnitsResolvedStateCache.js.map +1 -0
- package/lib/cjs/internal/DefaultPersistenceUnits.generated.d.ts +84 -0
- package/lib/cjs/internal/DefaultPersistenceUnits.generated.d.ts.map +1 -0
- package/lib/cjs/internal/DefaultPersistenceUnits.generated.js +94 -0
- package/lib/cjs/internal/DefaultPersistenceUnits.generated.js.map +1 -0
- package/lib/cjs/internal/UnitConversionMath.d.ts +21 -0
- package/lib/cjs/internal/UnitConversionMath.d.ts.map +1 -0
- package/lib/cjs/internal/UnitConversionMath.js +55 -0
- package/lib/cjs/internal/UnitConversionMath.js.map +1 -0
- package/lib/esm/BasicUnitsProvider.d.ts +8 -5
- package/lib/esm/BasicUnitsProvider.d.ts.map +1 -1
- package/lib/esm/BasicUnitsProvider.js +16 -139
- package/lib/esm/BasicUnitsProvider.js.map +1 -1
- package/lib/esm/Exception.d.ts +2 -1
- package/lib/esm/Exception.d.ts.map +1 -1
- package/lib/esm/Exception.js +1 -0
- package/lib/esm/Exception.js.map +1 -1
- package/lib/esm/FormatSpecHandle.d.ts +1 -2
- package/lib/esm/FormatSpecHandle.d.ts.map +1 -1
- package/lib/esm/FormatSpecHandle.js +0 -1
- package/lib/esm/FormatSpecHandle.js.map +1 -1
- package/lib/esm/Quantity.d.ts +4 -0
- package/lib/esm/Quantity.d.ts.map +1 -1
- package/lib/esm/Quantity.js +12 -23
- package/lib/esm/Quantity.js.map +1 -1
- package/lib/esm/UnitConversion/UnitConversion.js +1 -1
- package/lib/esm/UnitConversion/UnitConversion.js.map +1 -1
- package/lib/esm/UnitConversions.d.ts +40 -0
- package/lib/esm/UnitConversions.d.ts.map +1 -0
- package/lib/esm/UnitConversions.js +116 -0
- package/lib/esm/UnitConversions.js.map +1 -0
- package/lib/esm/assets/Units.json +72 -1
- package/lib/esm/core-quantity.d.ts +6 -0
- package/lib/esm/core-quantity.d.ts.map +1 -1
- package/lib/esm/core-quantity.js +6 -0
- package/lib/esm/core-quantity.js.map +1 -1
- package/lib/esm/generated/Units.generated.d.ts +785 -0
- package/lib/esm/generated/Units.generated.d.ts.map +1 -0
- package/lib/esm/generated/Units.generated.js +772 -0
- package/lib/esm/generated/Units.generated.js.map +1 -0
- package/lib/esm/internal/BasicUnitConversionData.d.ts +33 -0
- package/lib/esm/internal/BasicUnitConversionData.d.ts.map +1 -0
- package/lib/esm/internal/BasicUnitConversionData.js +122 -0
- package/lib/esm/internal/BasicUnitConversionData.js.map +1 -0
- package/lib/esm/internal/BasicUnitConversions.generated.d.ts +507 -0
- package/lib/esm/internal/BasicUnitConversions.generated.d.ts.map +1 -0
- package/lib/esm/internal/BasicUnitConversions.generated.js +512 -0
- package/lib/esm/internal/BasicUnitConversions.generated.js.map +1 -0
- package/lib/esm/internal/BasicUnitsResolvedStateCache.d.ts +12 -0
- package/lib/esm/internal/BasicUnitsResolvedStateCache.d.ts.map +1 -0
- package/lib/esm/internal/BasicUnitsResolvedStateCache.js +33 -0
- package/lib/esm/internal/BasicUnitsResolvedStateCache.js.map +1 -0
- package/lib/esm/internal/DefaultPersistenceUnits.generated.d.ts +84 -0
- package/lib/esm/internal/DefaultPersistenceUnits.generated.d.ts.map +1 -0
- package/lib/esm/internal/DefaultPersistenceUnits.generated.js +91 -0
- package/lib/esm/internal/DefaultPersistenceUnits.generated.js.map +1 -0
- package/lib/esm/internal/UnitConversionMath.d.ts +21 -0
- package/lib/esm/internal/UnitConversionMath.d.ts.map +1 -0
- package/lib/esm/internal/UnitConversionMath.js +49 -0
- package/lib/esm/internal/UnitConversionMath.js.map +1 -0
- package/package.json +10 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,31 @@
|
|
|
1
1
|
# Change Log - @itwin/core-quantity
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Wed, 03 Jun 2026 20:19:46 GMT and should not be manually modified.
|
|
4
|
+
|
|
5
|
+
## 5.10.0
|
|
6
|
+
Wed, 03 Jun 2026 20:19:46 GMT
|
|
7
|
+
|
|
8
|
+
### Updates
|
|
9
|
+
|
|
10
|
+
- Added BasicUnitsProvider (bundled BIS units), createUnitsProvider factory, and CreateUnitsProviderOptions interface. Added UnitConversion math, parseDefinition, and Graph utilities (moved from ecschema-metadata). Added SerializedUnitSchema types and UnitDefinitionResolver.
|
|
11
|
+
- Add generated unit schema names and UnitConversions helpers backed by bundled basic units
|
|
12
|
+
- Fix FormatSpecHandle stale state during onFormattingReady
|
|
13
|
+
- Use units schema 01.00.10
|
|
14
|
+
|
|
15
|
+
## 5.9.5
|
|
16
|
+
Mon, 01 Jun 2026 17:34:00 GMT
|
|
17
|
+
|
|
18
|
+
_Version update only_
|
|
19
|
+
|
|
20
|
+
## 5.9.4
|
|
21
|
+
Tue, 19 May 2026 19:45:27 GMT
|
|
22
|
+
|
|
23
|
+
_Version update only_
|
|
24
|
+
|
|
25
|
+
## 5.9.3
|
|
26
|
+
Fri, 15 May 2026 11:25:54 GMT
|
|
27
|
+
|
|
28
|
+
_Version update only_
|
|
4
29
|
|
|
5
30
|
## 5.9.2
|
|
6
31
|
Fri, 08 May 2026 20:36:41 GMT
|
|
@@ -25,6 +50,11 @@ Mon, 04 May 2026 16:32:08 GMT
|
|
|
25
50
|
|
|
26
51
|
- Added BasicUnitsProvider (bundled BIS units), createUnitsProvider factory, and CreateUnitsProviderOptions interface. Added UnitConversion math, parseDefinition, and Graph utilities (moved from ecschema-metadata). Added SerializedUnitSchema types and UnitDefinitionResolver.
|
|
27
52
|
|
|
53
|
+
## 5.8.5
|
|
54
|
+
Thu, 14 May 2026 19:12:21 GMT
|
|
55
|
+
|
|
56
|
+
_Version update only_
|
|
57
|
+
|
|
28
58
|
## 5.8.4
|
|
29
59
|
Thu, 23 Apr 2026 18:05:14 GMT
|
|
30
60
|
|
package/README.md
CHANGED
|
@@ -4,6 +4,23 @@ The __@itwin/core-quantity__ package contains classes for quantity formatting an
|
|
|
4
4
|
|
|
5
5
|
Also check the [iTwin.js learning documentation](https://www.itwinjs.org/learning/quantity) explaining quantity formatting and its basic concepts.
|
|
6
6
|
|
|
7
|
+
## Example
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { getDefaultPersistenceUnit, Phenomena, UnitConversions, Units } from "@itwin/core-quantity";
|
|
11
|
+
|
|
12
|
+
const persistenceUnit = getDefaultPersistenceUnit(Phenomena.LENGTH);
|
|
13
|
+
const feet = UnitConversions.convert(
|
|
14
|
+
persistenceUnit,
|
|
15
|
+
Units.LENGTH.FT,
|
|
16
|
+
1,
|
|
17
|
+
);
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
UnitConversions provides synchronous conversion helpers for the canonical unit set generated from `@bentley/units-schema`.
|
|
21
|
+
`getDefaultPersistenceUnit(...)` returns the package default persistence unit for a supported phenomenon.
|
|
22
|
+
`Phenomena.LENGTH_RATIO` is intentionally not supported by that helper yet because the bundled built-in unit set does not currently provide an agreed default for that phenomenon.
|
|
23
|
+
|
|
7
24
|
## Contributing
|
|
8
25
|
|
|
9
26
|
When adding new APIs or updating documentation for this package, review if [QuantityFormatting.md](https://github.com/iTwin/itwinjs-core/blob/master/docs/learning/frontend/QuantityFormatting.md) or the [core-quantity learning page](https://github.com/iTwin/itwinjs-core/blob/master/docs/learning/quantity/index.md) needs to be updated as well. When adding or editing code examples, it's encouraged to keep the examples consistent between this file and the linked file above.
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import
|
|
2
|
-
/** @internal — test use only. Resets the module-level lazy cache. */
|
|
1
|
+
import type { UnitProps, UnitsProvider } from "./Interfaces";
|
|
2
|
+
/** @internal — test use only. Resets the shared module-level lazy cache. */
|
|
3
3
|
export declare function _testResetUnitsCache(): void;
|
|
4
4
|
/**
|
|
5
5
|
* A `UnitsProvider` backed by the full BIS `Units.ecschema.json` bundled as a JSON asset.
|
|
6
6
|
*
|
|
7
|
-
* The
|
|
8
|
-
*
|
|
7
|
+
* The bundled JSON is loaded lazily via dynamic `import()` on the first provider call and cached
|
|
8
|
+
* at module scope — construction is essentially free, and multiple instances
|
|
9
9
|
* share the same immutable lookup indexes.
|
|
10
10
|
*
|
|
11
|
+
* If an initial schema load fails, later provider calls will retry the load instead of pinning the
|
|
12
|
+
* provider into a permanently failed module-level state.
|
|
13
|
+
*
|
|
11
14
|
* This is the zero-dependency default for backends, tools, and any frontend that doesn't need
|
|
12
15
|
* iModel overrides. Equivalent to calling `createUnitsProvider()` with no arguments.
|
|
13
16
|
*
|
|
@@ -39,6 +42,6 @@ export declare class BasicUnitsProvider implements UnitsProvider {
|
|
|
39
42
|
* @param toUnit - The target unit.
|
|
40
43
|
* @returns A `UnitConversionProps` with `factor`, `offset`, and optionally `inversion` and `error`.
|
|
41
44
|
*/
|
|
42
|
-
getConversion(fromUnit: UnitProps, toUnit: UnitProps): Promise<UnitConversionProps>;
|
|
45
|
+
getConversion(fromUnit: UnitProps, toUnit: UnitProps): Promise<import("./Interfaces").UnitConversionProps>;
|
|
43
46
|
}
|
|
44
47
|
//# sourceMappingURL=BasicUnitsProvider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BasicUnitsProvider.d.ts","sourceRoot":"","sources":["../../src/BasicUnitsProvider.ts"],"names":[],"mappings":"AAIA,OAAO,
|
|
1
|
+
{"version":3,"file":"BasicUnitsProvider.d.ts","sourceRoot":"","sources":["../../src/BasicUnitsProvider.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAe7D,4EAA4E;AAC5E,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,kBAAmB,YAAW,aAAa;IAItD;;;;;;OAMG;IACU,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAuB3H;;;OAGG;IACU,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAMvE;;;OAGG;IACU,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAMjE;;;;;OAKG;IACU,aAAa,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS;CAIlE"}
|
|
@@ -25,115 +25,31 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.BasicUnitsProvider = void 0;
|
|
27
27
|
exports._testResetUnitsCache = _testResetUnitsCache;
|
|
28
|
-
/*---------------------------------------------------------------------------------------------
|
|
29
|
-
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
30
|
-
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
31
|
-
*--------------------------------------------------------------------------------------------*/
|
|
32
|
-
const Interfaces_1 = require("./Interfaces");
|
|
33
|
-
const UnitDefinitionResolver_1 = require("./UnitConversion/UnitDefinitionResolver");
|
|
34
|
-
const nameUtils_1 = require("./UnitConversion/nameUtils");
|
|
35
28
|
const Unit_1 = require("./Unit");
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
// scope avoids redundant work when multiple BasicUnitsProvider instances are created (e.g.
|
|
39
|
-
// in tests or when composed inside CompositeUnitsProvider).
|
|
40
|
-
// The JSON is loaded lazily via dynamic import() on first use, keeping the module footprint
|
|
41
|
-
// near-zero until a provider method is actually called.
|
|
42
|
-
let _resolvePromise;
|
|
43
|
-
let _permanentError;
|
|
29
|
+
const BasicUnitConversionData_1 = require("./internal/BasicUnitConversionData");
|
|
30
|
+
const BasicUnitsResolvedStateCache_1 = require("./internal/BasicUnitsResolvedStateCache");
|
|
44
31
|
async function resolveState() {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
_resolvePromise = undefined;
|
|
52
|
-
throw _permanentError;
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
return _resolvePromise;
|
|
32
|
+
return (0, BasicUnitsResolvedStateCache_1.resolveBasicUnitsData)(async () => {
|
|
33
|
+
// First caller pays the dynamic-import + schema-index build cost.
|
|
34
|
+
// Concurrent callers await the same promise, and later callers reuse the resolved state.
|
|
35
|
+
const { default: schema } = await Promise.resolve().then(() => __importStar(require("./assets/Units.json")));
|
|
36
|
+
return schema;
|
|
37
|
+
});
|
|
56
38
|
}
|
|
57
|
-
/** @internal — test use only. Resets the module-level lazy cache. */
|
|
39
|
+
/** @internal — test use only. Resets the shared module-level lazy cache. */
|
|
58
40
|
function _testResetUnitsCache() {
|
|
59
|
-
|
|
60
|
-
_permanentError = undefined;
|
|
61
|
-
}
|
|
62
|
-
async function _buildState() {
|
|
63
|
-
const { default: schema } = await Promise.resolve().then(() => __importStar(require("./assets/Units.json")));
|
|
64
|
-
const nameMap = new Map();
|
|
65
|
-
const labelMap = new Map();
|
|
66
|
-
const phenomenonMap = new Map();
|
|
67
|
-
const invertedUnits = new Map();
|
|
68
|
-
const s = schema;
|
|
69
|
-
const resolver = new UnitDefinitionResolver_1.UnitDefinitionResolver(s);
|
|
70
|
-
const resolved = resolver.resolveAll();
|
|
71
|
-
for (const [name, entry] of resolved) {
|
|
72
|
-
const item = s.items[name];
|
|
73
|
-
const phenomenon = item.phenomenon;
|
|
74
|
-
const unitSystem = item.unitSystem;
|
|
75
|
-
const fullName = `${s.name}.${name}`;
|
|
76
|
-
const props = {
|
|
77
|
-
name: fullName,
|
|
78
|
-
label: entry.label,
|
|
79
|
-
phenomenon,
|
|
80
|
-
isValid: true,
|
|
81
|
-
system: unitSystem,
|
|
82
|
-
};
|
|
83
|
-
const indexed = { props, resolved: entry };
|
|
84
|
-
nameMap.set(fullName, indexed);
|
|
85
|
-
const lowerLabel = entry.label.toLowerCase();
|
|
86
|
-
const byLabel = labelMap.get(lowerLabel) ?? [];
|
|
87
|
-
byLabel.push(indexed);
|
|
88
|
-
labelMap.set(lowerLabel, byLabel);
|
|
89
|
-
const byPhen = phenomenonMap.get(phenomenon) ?? [];
|
|
90
|
-
byPhen.push(indexed);
|
|
91
|
-
phenomenonMap.set(phenomenon, byPhen);
|
|
92
|
-
}
|
|
93
|
-
// Handle InvertedUnit items — must run after nameMap is fully populated above because
|
|
94
|
-
// invertedSource lookup requires the inverted unit's target to already be in nameMap.
|
|
95
|
-
for (const [name, item] of Object.entries(s.items)) {
|
|
96
|
-
if (item.schemaItemType !== "InvertedUnit") {
|
|
97
|
-
continue;
|
|
98
|
-
}
|
|
99
|
-
const inv = item;
|
|
100
|
-
const fullName = `${s.name}.${name}`;
|
|
101
|
-
const invertsName = (0, nameUtils_1.qualifyItemName)(inv.invertsUnit, s.name);
|
|
102
|
-
const unitSystem = inv.unitSystem;
|
|
103
|
-
const invertedSource = nameMap.get(invertsName);
|
|
104
|
-
const phenomenon = invertedSource?.props.phenomenon ?? "";
|
|
105
|
-
const props = {
|
|
106
|
-
name: fullName,
|
|
107
|
-
label: inv.label ?? name,
|
|
108
|
-
phenomenon,
|
|
109
|
-
isValid: true,
|
|
110
|
-
system: unitSystem,
|
|
111
|
-
};
|
|
112
|
-
invertedUnits.set(fullName, { props, invertsUnitName: invertsName });
|
|
113
|
-
if (invertedSource) {
|
|
114
|
-
const indexed = {
|
|
115
|
-
props,
|
|
116
|
-
resolved: { ...invertedSource.resolved, name: fullName, label: props.label, unitSystem },
|
|
117
|
-
};
|
|
118
|
-
nameMap.set(fullName, indexed);
|
|
119
|
-
const lowerLabel = props.label.toLowerCase();
|
|
120
|
-
const byLabel = labelMap.get(lowerLabel) ?? [];
|
|
121
|
-
byLabel.push(indexed);
|
|
122
|
-
labelMap.set(lowerLabel, byLabel);
|
|
123
|
-
const byPhen = phenomenonMap.get(phenomenon) ?? [];
|
|
124
|
-
byPhen.push(indexed);
|
|
125
|
-
phenomenonMap.set(phenomenon, byPhen);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
return { nameMap, labelMap, phenomenonMap, invertedUnits, schemaName: s.name };
|
|
41
|
+
(0, BasicUnitsResolvedStateCache_1._testResetResolvedBasicUnitsDataCache)();
|
|
129
42
|
}
|
|
130
43
|
/**
|
|
131
44
|
* A `UnitsProvider` backed by the full BIS `Units.ecschema.json` bundled as a JSON asset.
|
|
132
45
|
*
|
|
133
|
-
* The
|
|
134
|
-
*
|
|
46
|
+
* The bundled JSON is loaded lazily via dynamic `import()` on the first provider call and cached
|
|
47
|
+
* at module scope — construction is essentially free, and multiple instances
|
|
135
48
|
* share the same immutable lookup indexes.
|
|
136
49
|
*
|
|
50
|
+
* If an initial schema load fails, later provider calls will retry the load instead of pinning the
|
|
51
|
+
* provider into a permanently failed module-level state.
|
|
52
|
+
*
|
|
137
53
|
* This is the zero-dependency default for backends, tools, and any frontend that doesn't need
|
|
138
54
|
* iModel overrides. Equivalent to calling `createUnitsProvider()` with no arguments.
|
|
139
55
|
*
|
|
@@ -195,46 +111,7 @@ class BasicUnitsProvider {
|
|
|
195
111
|
*/
|
|
196
112
|
async getConversion(fromUnit, toUnit) {
|
|
197
113
|
const state = await resolveState();
|
|
198
|
-
|
|
199
|
-
const to = state.nameMap.get(toUnit.name);
|
|
200
|
-
if (!from || !to) {
|
|
201
|
-
return { factor: 1.0, offset: 0.0, error: true };
|
|
202
|
-
}
|
|
203
|
-
const fromInverted = state.invertedUnits.get(fromUnit.name);
|
|
204
|
-
const toInverted = state.invertedUnits.get(toUnit.name);
|
|
205
|
-
const fromPhenomenon = fromInverted
|
|
206
|
-
? state.nameMap.get(fromInverted.invertsUnitName)?.props.phenomenon
|
|
207
|
-
: from.props.phenomenon;
|
|
208
|
-
const toPhenomenon = toInverted
|
|
209
|
-
? state.nameMap.get(toInverted.invertsUnitName)?.props.phenomenon
|
|
210
|
-
: to.props.phenomenon;
|
|
211
|
-
if (fromPhenomenon !== toPhenomenon) {
|
|
212
|
-
return { factor: 1.0, offset: 0.0, error: true };
|
|
213
|
-
}
|
|
214
|
-
if (fromInverted && toInverted) {
|
|
215
|
-
const innerFrom = state.nameMap.get(fromInverted.invertsUnitName);
|
|
216
|
-
const innerTo = state.nameMap.get(toInverted.invertsUnitName);
|
|
217
|
-
if (innerFrom && innerTo) {
|
|
218
|
-
const c = innerFrom.resolved.conversion.inverse().compose(innerTo.resolved.conversion);
|
|
219
|
-
return { factor: c.factor, offset: c.offset };
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
if (fromInverted) {
|
|
223
|
-
const innerFrom = state.nameMap.get(fromInverted.invertsUnitName);
|
|
224
|
-
if (innerFrom) {
|
|
225
|
-
const c = innerFrom.resolved.conversion.inverse().compose(to.resolved.conversion);
|
|
226
|
-
return { factor: c.factor, offset: c.offset, inversion: Interfaces_1.UnitConversionInvert.InvertPreConversion };
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
if (toInverted) {
|
|
230
|
-
const innerTo = state.nameMap.get(toInverted.invertsUnitName);
|
|
231
|
-
if (innerTo) {
|
|
232
|
-
const c = from.resolved.conversion.inverse().compose(innerTo.resolved.conversion);
|
|
233
|
-
return { factor: c.factor, offset: c.offset, inversion: Interfaces_1.UnitConversionInvert.InvertPostConversion };
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
const conv = from.resolved.conversion.inverse().compose(to.resolved.conversion);
|
|
237
|
-
return { factor: conv.factor, offset: conv.offset };
|
|
114
|
+
return (0, BasicUnitConversionData_1.getBasicUnitConversion)(state, fromUnit, toUnit);
|
|
238
115
|
}
|
|
239
116
|
}
|
|
240
117
|
exports.BasicUnitsProvider = BasicUnitsProvider;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BasicUnitsProvider.js","sourceRoot":"","sources":["../../src/BasicUnitsProvider.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nimport { UnitConversionInvert, type UnitConversionProps, type UnitProps, type UnitsProvider } from \"./Interfaces\";\nimport type { SerializedInvertedUnit, SerializedUnit, SerializedUnitSchema } from \"./SerializedUnitSchema\";\nimport { type ResolvedUnit, UnitDefinitionResolver } from \"./UnitConversion/UnitDefinitionResolver\";\nimport { qualifyItemName } from \"./UnitConversion/nameUtils\";\nimport { BadUnit } from \"./Unit\";\n\ninterface IndexedUnit {\n readonly props: UnitProps;\n readonly resolved: ResolvedUnit;\n}\n\ninterface InvertedEntry {\n readonly props: UnitProps;\n readonly invertsUnitName: string;\n}\n\n/** Immutable lookup indexes resolved from the bundled Units.json. */\ninterface ResolvedState {\n readonly nameMap: Map<string, IndexedUnit>;\n readonly labelMap: Map<string, IndexedUnit[]>;\n readonly phenomenonMap: Map<string, IndexedUnit[]>;\n readonly invertedUnits: Map<string, InvertedEntry>;\n readonly schemaName: string;\n}\n\n// Module-level cache: the unit data is derived deterministically from the bundled Units.json\n// asset, so the resolved indexes are effectively an immutable constant. Caching at module\n// scope avoids redundant work when multiple BasicUnitsProvider instances are created (e.g.\n// in tests or when composed inside CompositeUnitsProvider).\n// The JSON is loaded lazily via dynamic import() on first use, keeping the module footprint\n// near-zero until a provider method is actually called.\nlet _resolvePromise: Promise<ResolvedState> | undefined;\nlet _permanentError: Error | undefined;\n\nasync function resolveState(): Promise<ResolvedState> {\n if (_permanentError !== undefined) {\n throw _permanentError;\n }\n if (!_resolvePromise) {\n _resolvePromise = _buildState().catch((err) => {\n _permanentError = err instanceof Error ? err : new Error(String(err));\n _resolvePromise = undefined;\n throw _permanentError;\n });\n }\n return _resolvePromise;\n}\n\n/** @internal — test use only. Resets the module-level lazy cache. */\nexport function _testResetUnitsCache(): void {\n _resolvePromise = undefined;\n _permanentError = undefined;\n}\n\nasync function _buildState(): Promise<ResolvedState> {\n const { default: schema } = await import(\"./assets/Units.json\");\n\n const nameMap = new Map<string, IndexedUnit>();\n const labelMap = new Map<string, IndexedUnit[]>();\n const phenomenonMap = new Map<string, IndexedUnit[]>();\n const invertedUnits = new Map<string, InvertedEntry>();\n\n const s = schema as SerializedUnitSchema;\n const resolver = new UnitDefinitionResolver(s);\n const resolved = resolver.resolveAll();\n\n for (const [name, entry] of resolved) {\n const item = s.items[name] as SerializedUnit;\n const phenomenon = item.phenomenon;\n const unitSystem = item.unitSystem;\n\n const fullName = `${s.name}.${name}`;\n const props: UnitProps = {\n name: fullName,\n label: entry.label,\n phenomenon,\n isValid: true,\n system: unitSystem,\n };\n\n const indexed: IndexedUnit = { props, resolved: entry };\n\n nameMap.set(fullName, indexed);\n const lowerLabel = entry.label.toLowerCase();\n const byLabel = labelMap.get(lowerLabel) ?? [];\n byLabel.push(indexed);\n labelMap.set(lowerLabel, byLabel);\n\n const byPhen = phenomenonMap.get(phenomenon) ?? [];\n byPhen.push(indexed);\n phenomenonMap.set(phenomenon, byPhen);\n }\n\n // Handle InvertedUnit items — must run after nameMap is fully populated above because\n // invertedSource lookup requires the inverted unit's target to already be in nameMap.\n for (const [name, item] of Object.entries(s.items)) {\n if (item.schemaItemType !== \"InvertedUnit\") {\n continue;\n }\n const inv: SerializedInvertedUnit = item;\n const fullName = `${s.name}.${name}`;\n const invertsName = qualifyItemName(inv.invertsUnit, s.name);\n const unitSystem = inv.unitSystem;\n\n const invertedSource = nameMap.get(invertsName);\n const phenomenon = invertedSource?.props.phenomenon ?? \"\";\n\n const props: UnitProps = {\n name: fullName,\n label: inv.label ?? name,\n phenomenon,\n isValid: true,\n system: unitSystem,\n };\n\n invertedUnits.set(fullName, { props, invertsUnitName: invertsName });\n\n if (invertedSource) {\n const indexed: IndexedUnit = {\n props,\n resolved: { ...invertedSource.resolved, name: fullName, label: props.label, unitSystem },\n };\n nameMap.set(fullName, indexed);\n\n const lowerLabel = props.label.toLowerCase();\n const byLabel = labelMap.get(lowerLabel) ?? [];\n byLabel.push(indexed);\n labelMap.set(lowerLabel, byLabel);\n\n const byPhen = phenomenonMap.get(phenomenon) ?? [];\n byPhen.push(indexed);\n phenomenonMap.set(phenomenon, byPhen);\n }\n }\n\n return { nameMap, labelMap, phenomenonMap, invertedUnits, schemaName: s.name };\n}\n\n/**\n * A `UnitsProvider` backed by the full BIS `Units.ecschema.json` bundled as a JSON asset.\n *\n * The ~90 KB bundled JSON is loaded lazily via dynamic `import()` on the first provider method\n * call and cached at module scope — construction is essentially free, and multiple instances\n * share the same immutable lookup indexes.\n *\n * This is the zero-dependency default for backends, tools, and any frontend that doesn't need\n * iModel overrides. Equivalent to calling `createUnitsProvider()` with no arguments.\n *\n * @see createUnitsProvider for layering schema-defined units on top of basic BIS units.\n * @beta\n */\nexport class BasicUnitsProvider implements UnitsProvider {\n\n // ── UnitsProvider implementation ─────────────────────────────────────\n\n /** Find a unit by its display label, optionally filtering by schema name, phenomenon, and unit system.\n * @param unitLabel - The display label to search for (case-insensitive).\n * @param schemaName - Optional schema name filter. Returns `BadUnit` if provided and not `\"Units\"`.\n * @param phenomenon - Optional phenomenon filter (e.g. `\"Units.LENGTH\"`).\n * @param unitSystem - Optional unit system filter (e.g. `\"Units.METRIC\"`).\n * @returns The matching `UnitProps`, or a `BadUnit` if no match is found.\n */\n public async findUnit(unitLabel: string, schemaName?: string, phenomenon?: string, unitSystem?: string): Promise<UnitProps> {\n const state = await resolveState();\n if (schemaName && schemaName !== state.schemaName) {\n return new BadUnit();\n }\n const candidates = state.labelMap.get(unitLabel.toLowerCase());\n if (!candidates || candidates.length === 0) {\n return new BadUnit();\n }\n\n for (const c of candidates) {\n if (phenomenon && c.props.phenomenon !== phenomenon) {\n continue;\n }\n if (unitSystem && c.props.system !== unitSystem) {\n continue;\n }\n return c.props;\n }\n\n return new BadUnit();\n }\n\n /** Return all units belonging to the given phenomenon (unit family).\n * @param phenomenon - The phenomenon full name (e.g. `\"Units.LENGTH\"`).\n * @returns An array of matching `UnitProps`, or an empty array if none.\n */\n public async getUnitsByFamily(phenomenon: string): Promise<UnitProps[]> {\n const state = await resolveState();\n const entries = state.phenomenonMap.get(phenomenon);\n return entries ? entries.map((e) => e.props) : [];\n }\n\n /** Find a unit by its fully-qualified name (e.g. `\"Units.M\"`).\n * @param unitName - The qualified unit name.\n * @returns The matching `UnitProps`, or a `BadUnit` if not found.\n */\n public async findUnitByName(unitName: string): Promise<UnitProps> {\n const state = await resolveState();\n const entry = state.nameMap.get(unitName);\n return entry ? entry.props : new BadUnit();\n }\n\n /** Compute the conversion factors from `fromUnit` to `toUnit`.\n * Handles normal units, inverted units, and mixed (inverted ↔ non-inverted) conversions.\n * @param fromUnit - The source unit.\n * @param toUnit - The target unit.\n * @returns A `UnitConversionProps` with `factor`, `offset`, and optionally `inversion` and `error`.\n */\n public async getConversion(fromUnit: UnitProps, toUnit: UnitProps): Promise<UnitConversionProps> {\n const state = await resolveState();\n const from = state.nameMap.get(fromUnit.name);\n const to = state.nameMap.get(toUnit.name);\n\n if (!from || !to) {\n return { factor: 1.0, offset: 0.0, error: true };\n }\n\n const fromInverted = state.invertedUnits.get(fromUnit.name);\n const toInverted = state.invertedUnits.get(toUnit.name);\n\n const fromPhenomenon = fromInverted\n ? state.nameMap.get(fromInverted.invertsUnitName)?.props.phenomenon\n : from.props.phenomenon;\n const toPhenomenon = toInverted\n ? state.nameMap.get(toInverted.invertsUnitName)?.props.phenomenon\n : to.props.phenomenon;\n if (fromPhenomenon !== toPhenomenon) {\n return { factor: 1.0, offset: 0.0, error: true };\n }\n\n if (fromInverted && toInverted) {\n const innerFrom = state.nameMap.get(fromInverted.invertsUnitName);\n const innerTo = state.nameMap.get(toInverted.invertsUnitName);\n if (innerFrom && innerTo) {\n const c = innerFrom.resolved.conversion.inverse().compose(innerTo.resolved.conversion);\n return { factor: c.factor, offset: c.offset };\n }\n }\n\n if (fromInverted) {\n const innerFrom = state.nameMap.get(fromInverted.invertsUnitName);\n if (innerFrom) {\n const c = innerFrom.resolved.conversion.inverse().compose(to.resolved.conversion);\n return { factor: c.factor, offset: c.offset, inversion: UnitConversionInvert.InvertPreConversion };\n }\n }\n\n if (toInverted) {\n const innerTo = state.nameMap.get(toInverted.invertsUnitName);\n if (innerTo) {\n const c = from.resolved.conversion.inverse().compose(innerTo.resolved.conversion);\n return { factor: c.factor, offset: c.offset, inversion: UnitConversionInvert.InvertPostConversion };\n }\n }\n\n const conv = from.resolved.conversion.inverse().compose(to.resolved.conversion);\n return { factor: conv.factor, offset: conv.offset };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"BasicUnitsProvider.js","sourceRoot":"","sources":["../../src/BasicUnitsProvider.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAoBA,oDAEC;AAhBD,iCAAiC;AACjC,gFAA4E;AAC5E,0FAAuH;AAEvH,KAAK,UAAU,YAAY;IACzB,OAAO,IAAA,oDAAqB,EAAC,KAAK,IAAI,EAAE;QACtC,kEAAkE;QAClE,yFAAyF;QACzF,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,wDAAa,qBAAqB,GAAC,CAAC;QAChE,OAAO,MAA8B,CAAC;IACxC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,4EAA4E;AAC5E,SAAgB,oBAAoB;IAClC,IAAA,oEAAqC,GAAE,CAAC;AAC1C,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAa,kBAAkB;IAE7B,wEAAwE;IAExE;;;;;;OAMG;IACI,KAAK,CAAC,QAAQ,CAAC,SAAiB,EAAE,UAAmB,EAAE,UAAmB,EAAE,UAAmB;QACpG,MAAM,KAAK,GAAG,MAAM,YAAY,EAAE,CAAC;QACnC,IAAI,UAAU,IAAI,UAAU,KAAK,KAAK,CAAC,UAAU,EAAE,CAAC;YAClD,OAAO,IAAI,cAAO,EAAE,CAAC;QACvB,CAAC;QACD,MAAM,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC;QAC/D,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3C,OAAO,IAAI,cAAO,EAAE,CAAC;QACvB,CAAC;QAED,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;YAC3B,IAAI,UAAU,IAAI,CAAC,CAAC,KAAK,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;gBACpD,SAAS;YACX,CAAC;YACD,IAAI,UAAU,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;gBAChD,SAAS;YACX,CAAC;YACD,OAAO,CAAC,CAAC,KAAK,CAAC;QACjB,CAAC;QAED,OAAO,IAAI,cAAO,EAAE,CAAC;IACvB,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,gBAAgB,CAAC,UAAkB;QAC9C,MAAM,KAAK,GAAG,MAAM,YAAY,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACpD,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACpD,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,cAAc,CAAC,QAAgB;QAC1C,MAAM,KAAK,GAAG,MAAM,YAAY,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC1C,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,cAAO,EAAE,CAAC;IAC7C,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,aAAa,CAAC,QAAmB,EAAE,MAAiB;QAC/D,MAAM,KAAK,GAAG,MAAM,YAAY,EAAE,CAAC;QACnC,OAAO,IAAA,gDAAsB,EAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IACzD,CAAC;CACF;AAhED,gDAgEC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\nimport type { UnitProps, UnitsProvider } from \"./Interfaces\";\nimport type { SerializedUnitSchema } from \"./SerializedUnitSchema\";\nimport { BadUnit } from \"./Unit\";\nimport { getBasicUnitConversion } from \"./internal/BasicUnitConversionData\";\nimport { _testResetResolvedBasicUnitsDataCache, resolveBasicUnitsData } from \"./internal/BasicUnitsResolvedStateCache\";\n\nasync function resolveState() {\n return resolveBasicUnitsData(async () => {\n // First caller pays the dynamic-import + schema-index build cost.\n // Concurrent callers await the same promise, and later callers reuse the resolved state.\n const { default: schema } = await import(\"./assets/Units.json\");\n return schema as SerializedUnitSchema;\n });\n}\n\n/** @internal — test use only. Resets the shared module-level lazy cache. */\nexport function _testResetUnitsCache(): void {\n _testResetResolvedBasicUnitsDataCache();\n}\n\n/**\n * A `UnitsProvider` backed by the full BIS `Units.ecschema.json` bundled as a JSON asset.\n *\n * The bundled JSON is loaded lazily via dynamic `import()` on the first provider call and cached\n * at module scope — construction is essentially free, and multiple instances\n * share the same immutable lookup indexes.\n *\n * If an initial schema load fails, later provider calls will retry the load instead of pinning the\n * provider into a permanently failed module-level state.\n *\n * This is the zero-dependency default for backends, tools, and any frontend that doesn't need\n * iModel overrides. Equivalent to calling `createUnitsProvider()` with no arguments.\n *\n * @see createUnitsProvider for layering schema-defined units on top of basic BIS units.\n * @beta\n */\nexport class BasicUnitsProvider implements UnitsProvider {\n\n // ── UnitsProvider implementation ─────────────────────────────────────\n\n /** Find a unit by its display label, optionally filtering by schema name, phenomenon, and unit system.\n * @param unitLabel - The display label to search for (case-insensitive).\n * @param schemaName - Optional schema name filter. Returns `BadUnit` if provided and not `\"Units\"`.\n * @param phenomenon - Optional phenomenon filter (e.g. `\"Units.LENGTH\"`).\n * @param unitSystem - Optional unit system filter (e.g. `\"Units.METRIC\"`).\n * @returns The matching `UnitProps`, or a `BadUnit` if no match is found.\n */\n public async findUnit(unitLabel: string, schemaName?: string, phenomenon?: string, unitSystem?: string): Promise<UnitProps> {\n const state = await resolveState();\n if (schemaName && schemaName !== state.schemaName) {\n return new BadUnit();\n }\n const candidates = state.labelMap.get(unitLabel.toLowerCase());\n if (!candidates || candidates.length === 0) {\n return new BadUnit();\n }\n\n for (const c of candidates) {\n if (phenomenon && c.props.phenomenon !== phenomenon) {\n continue;\n }\n if (unitSystem && c.props.system !== unitSystem) {\n continue;\n }\n return c.props;\n }\n\n return new BadUnit();\n }\n\n /** Return all units belonging to the given phenomenon (unit family).\n * @param phenomenon - The phenomenon full name (e.g. `\"Units.LENGTH\"`).\n * @returns An array of matching `UnitProps`, or an empty array if none.\n */\n public async getUnitsByFamily(phenomenon: string): Promise<UnitProps[]> {\n const state = await resolveState();\n const entries = state.phenomenonMap.get(phenomenon);\n return entries ? entries.map((e) => e.props) : [];\n }\n\n /** Find a unit by its fully-qualified name (e.g. `\"Units.M\"`).\n * @param unitName - The qualified unit name.\n * @returns The matching `UnitProps`, or a `BadUnit` if not found.\n */\n public async findUnitByName(unitName: string): Promise<UnitProps> {\n const state = await resolveState();\n const entry = state.nameMap.get(unitName);\n return entry ? entry.props : new BadUnit();\n }\n\n /** Compute the conversion factors from `fromUnit` to `toUnit`.\n * Handles normal units, inverted units, and mixed (inverted ↔ non-inverted) conversions.\n * @param fromUnit - The source unit.\n * @param toUnit - The target unit.\n * @returns A `UnitConversionProps` with `factor`, `offset`, and optionally `inversion` and `error`.\n */\n public async getConversion(fromUnit: UnitProps, toUnit: UnitProps) {\n const state = await resolveState();\n return getBasicUnitConversion(state, fromUnit, toUnit);\n }\n}\n"]}
|
package/lib/cjs/Exception.d.ts
CHANGED
|
@@ -18,7 +18,8 @@ export declare enum QuantityStatus {
|
|
|
18
18
|
UnableToConvertParseTokensToQuantity = 35046,
|
|
19
19
|
UnsupportedUnit = 35047,
|
|
20
20
|
MissingRequiredProperty = 35048,
|
|
21
|
-
InvertingZero = 35049
|
|
21
|
+
InvertingZero = 35049,
|
|
22
|
+
InvalidUnitConversion = 35050
|
|
22
23
|
}
|
|
23
24
|
/** The error type thrown by this module. See [[QuantityStatus]] for `errorNumber` values.
|
|
24
25
|
* @beta
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Exception.d.ts","sourceRoot":"","sources":["../../src/Exception.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAU,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE3D;;;GAGG;AACH,oBAAY,cAAc;IACxB,mBAAmB,QAAS;IAC5B,OAAO,IAAI;IACX,WAAW,QAA0B;IACrC,sBAAsB,QAA0B;IAChD,2BAA2B,QAA0B;IACrD,0BAA0B,QAA0B;IACpD,8BAA8B,QAA0B;IACxD,WAAW,QAA0B;IACrC,oCAAoC,QAA0B;IAC9D,eAAe,QAA0B;IACzC,uBAAuB,QAA0B;IACjD,aAAa,QAA2B;
|
|
1
|
+
{"version":3,"file":"Exception.d.ts","sourceRoot":"","sources":["../../src/Exception.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAU,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE3D;;;GAGG;AACH,oBAAY,cAAc;IACxB,mBAAmB,QAAS;IAC5B,OAAO,IAAI;IACX,WAAW,QAA0B;IACrC,sBAAsB,QAA0B;IAChD,2BAA2B,QAA0B;IACrD,0BAA0B,QAA0B;IACpD,8BAA8B,QAA0B;IACxD,WAAW,QAA0B;IACrC,oCAAoC,QAA0B;IAC9D,eAAe,QAA0B;IACzC,uBAAuB,QAA0B;IACjD,aAAa,QAA2B;IACxC,qBAAqB,QAA2B;CACjD;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,YAAY;aACD,WAAW,EAAE,MAAM;gBAAnB,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;CAIlF"}
|
package/lib/cjs/Exception.js
CHANGED
|
@@ -27,6 +27,7 @@ var QuantityStatus;
|
|
|
27
27
|
QuantityStatus[QuantityStatus["UnsupportedUnit"] = 35047] = "UnsupportedUnit";
|
|
28
28
|
QuantityStatus[QuantityStatus["MissingRequiredProperty"] = 35048] = "MissingRequiredProperty";
|
|
29
29
|
QuantityStatus[QuantityStatus["InvertingZero"] = 35049] = "InvertingZero";
|
|
30
|
+
QuantityStatus[QuantityStatus["InvalidUnitConversion"] = 35050] = "InvalidUnitConversion";
|
|
30
31
|
})(QuantityStatus || (exports.QuantityStatus = QuantityStatus = {}));
|
|
31
32
|
/** The error type thrown by this module. See [[QuantityStatus]] for `errorNumber` values.
|
|
32
33
|
* @beta
|
package/lib/cjs/Exception.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Exception.js","sourceRoot":"","sources":["../../src/Exception.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;AAEH,sDAA2D;AAE3D;;;GAGG;AACH,IAAY,
|
|
1
|
+
{"version":3,"file":"Exception.js","sourceRoot":"","sources":["../../src/Exception.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;AAEH,sDAA2D;AAE3D;;;GAGG;AACH,IAAY,cAcX;AAdD,WAAY,cAAc;IACxB,qFAA4B,CAAA;IAC5B,yDAAW,CAAA;IACX,qEAAqC,CAAA;IACrC,2FAAgD,CAAA;IAChD,qGAAqD,CAAA;IACrD,mGAAoD,CAAA;IACpD,2GAAwD,CAAA;IACxD,qEAAqC,CAAA;IACrC,uHAA8D,CAAA;IAC9D,6EAAyC,CAAA;IACzC,6FAAiD,CAAA;IACjD,yEAAwC,CAAA;IACxC,yFAAgD,CAAA;AAClD,CAAC,EAdW,cAAc,8BAAd,cAAc,QAczB;AAED;;GAEG;AACH,MAAa,aAAc,SAAQ,2BAAY;IACD;IAA5C,YAA4C,WAAmB,EAAE,OAAgB;QAC/E,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QADc,gBAAW,GAAX,WAAW,CAAQ;QAE7D,IAAA,qBAAM,EAAC,WAAW,KAAK,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC1D,CAAC;CACF;AALD,sCAKC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Quantity\n */\n\nimport { assert, BentleyError } from \"@itwin/core-bentley\";\n\n/**\n * Status codes used during Quantity parsing and formatting processing.\n * @beta\n */\nexport enum QuantityStatus {\n QUANTITY_ERROR_BASE = 0x88DF,\n Success = 0,\n InvalidJson = QUANTITY_ERROR_BASE + 1,\n InvalidCompositeFormat = QUANTITY_ERROR_BASE + 2,\n UnableToGenerateParseTokens = QUANTITY_ERROR_BASE + 3,\n NoValueOrUnitFoundInString = QUANTITY_ERROR_BASE + 4,\n UnitLabelSuppliedButNotMatched = QUANTITY_ERROR_BASE + 5,\n UnknownUnit = QUANTITY_ERROR_BASE + 6,\n UnableToConvertParseTokensToQuantity = QUANTITY_ERROR_BASE + 7,\n UnsupportedUnit = QUANTITY_ERROR_BASE + 8,\n MissingRequiredProperty = QUANTITY_ERROR_BASE + 9,\n InvertingZero = QUANTITY_ERROR_BASE + 10,\n InvalidUnitConversion = QUANTITY_ERROR_BASE + 11,\n}\n\n/** The error type thrown by this module. See [[QuantityStatus]] for `errorNumber` values.\n * @beta\n */\nexport class QuantityError extends BentleyError {\n public constructor(public override readonly errorNumber: number, message?: string) {\n super(errorNumber, message);\n assert(errorNumber !== QuantityStatus.Success, message);\n }\n}\n"]}
|
|
@@ -6,7 +6,7 @@ import type { FormattingSpecArgs, FormattingSpecProvider } from "./Formatter/Int
|
|
|
6
6
|
import type { ParserSpec } from "./ParserSpec";
|
|
7
7
|
import type { UnitSystemKey } from "./Interfaces";
|
|
8
8
|
/** Arguments for constructing a [[FormatSpecHandle]].
|
|
9
|
-
* @
|
|
9
|
+
* @beta
|
|
10
10
|
*/
|
|
11
11
|
export interface FormatSpecHandleArgs extends FormattingSpecArgs {
|
|
12
12
|
/** The provider that supplies current formatting spec lookups. */
|
|
@@ -27,7 +27,6 @@ export declare class FormatSpecHandle implements Disposable {
|
|
|
27
27
|
private readonly _koqName;
|
|
28
28
|
private readonly _persistenceUnit;
|
|
29
29
|
private readonly _system;
|
|
30
|
-
/** @internal */
|
|
31
30
|
constructor(args: FormatSpecHandleArgs);
|
|
32
31
|
/** The KoQ name this handle is keyed to. */
|
|
33
32
|
get koqName(): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormatSpecHandle.d.ts","sourceRoot":"","sources":["../../src/FormatSpecHandle.ts"],"names":[],"mappings":"AAKA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAuB,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAC9G,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAC9D,kEAAkE;IAClE,QAAQ,EAAE,sBAAsB,CAAC;CAClC;AAED;;;;;;;;GAQG;AACH,qBAAa,gBAAiB,YAAW,UAAU;IACjD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;
|
|
1
|
+
{"version":3,"file":"FormatSpecHandle.d.ts","sourceRoot":"","sources":["../../src/FormatSpecHandle.ts"],"names":[],"mappings":"AAKA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAuB,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAC9G,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAC9D,kEAAkE;IAClE,QAAQ,EAAE,sBAAsB,CAAC;CAClC;AAED;;;;;;;;GAQG;AACH,qBAAa,gBAAiB,YAAW,UAAU;IACjD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;gBAExC,IAAI,EAAE,oBAAoB;IAOtC,4CAA4C;IAC5C,IAAW,OAAO,IAAI,MAAM,CAA0B;IAEtD,oDAAoD;IACpD,IAAW,eAAe,IAAI,MAAM,CAAkC;IAEtE,sFAAsF;IACtF,IAAW,MAAM,IAAI,aAAa,GAAG,SAAS,CAAyB;IAEvE,iEAAiE;IACjE,IAAW,aAAa,IAAI,aAAa,GAAG,SAAS,CAA4C;IAEjG,8DAA8D;IAC9D,IAAW,UAAU,IAAI,UAAU,GAAG,SAAS,CAAyC;IAExF;;;;OAIG;IACI,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAOpC;;;OAGG;IACI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI;IAI/B,OAAO,CAAC,SAAS;CAUlB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormatSpecHandle.js","sourceRoot":"","sources":["../../src/FormatSpecHandle.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;;;AAmB/F;;;;;;;;GAQG;AACH,MAAa,gBAAgB;IACnB,SAAS,GAAG,KAAK,CAAC;IACT,SAAS,CAAyB;IAClC,QAAQ,CAAS;IACjB,gBAAgB,CAAS;IACzB,OAAO,CAA4B;IAEpD,
|
|
1
|
+
{"version":3,"file":"FormatSpecHandle.js","sourceRoot":"","sources":["../../src/FormatSpecHandle.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;;;AAmB/F;;;;;;;;GAQG;AACH,MAAa,gBAAgB;IACnB,SAAS,GAAG,KAAK,CAAC;IACT,SAAS,CAAyB;IAClC,QAAQ,CAAS;IACjB,gBAAgB,CAAS;IACzB,OAAO,CAA4B;IAEpD,YAAY,IAA0B;QACpC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC/B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC;QAC1B,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,mBAAmB,CAAC;QACjD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED,4CAA4C;IAC5C,IAAW,OAAO,KAAa,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEtD,oDAAoD;IACpD,IAAW,eAAe,KAAa,OAAO,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEtE,sFAAsF;IACtF,IAAW,MAAM,KAAgC,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAEvE,iEAAiE;IACjE,IAAW,aAAa,KAAgC,OAAO,IAAI,CAAC,SAAS,EAAE,EAAE,aAAa,CAAC,CAAC,CAAC;IAEjG,8DAA8D;IAC9D,IAAW,UAAU,KAA6B,OAAO,IAAI,CAAC,SAAS,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC;IAExF;;;;OAIG;IACI,MAAM,CAAC,KAAa;QACzB,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;QACzC,IAAI,CAAC,aAAa;YAChB,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;IAC7D,CAAC;IAED;;;OAGG;IACI,CAAC,MAAM,CAAC,OAAO,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACxB,CAAC;IAEO,SAAS;QACf,IAAI,IAAI,CAAC,SAAS;YAChB,OAAO,SAAS,CAAC;QAEnB,OAAO,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAAC;YAC1C,IAAI,EAAE,IAAI,CAAC,QAAQ;YACnB,mBAAmB,EAAE,IAAI,CAAC,gBAAgB;YAC1C,MAAM,EAAE,IAAI,CAAC,OAAO;SACrB,CAAC,CAAC;IACL,CAAC;CACF;AA3DD,4CA2DC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\n/** @packageDocumentation\n * @module Quantity\n */\n\nimport type { FormatterSpec } from \"./Formatter/FormatterSpec\";\nimport type { FormattingSpecArgs, FormattingSpecEntry, FormattingSpecProvider } from \"./Formatter/Interfaces\";\nimport type { ParserSpec } from \"./ParserSpec\";\nimport type { UnitSystemKey } from \"./Interfaces\";\n\n/** Arguments for constructing a [[FormatSpecHandle]].\n * @beta\n */\nexport interface FormatSpecHandleArgs extends FormattingSpecArgs {\n /** The provider that supplies current formatting spec lookups. */\n provider: FormattingSpecProvider;\n}\n\n/** A handle to formatting and parsing specs for a specific KoQ and persistence unit.\n * Reads the current specs from the provider on access. Use [[QuantityFormatter.getFormatSpecHandle]]\n * to create instances.\n *\n * When formatting is not yet ready, [[format]] returns a `value.toString()` fallback.\n * Dispose the handle when it is no longer needed to invalidate it.\n *\n * @beta\n */\nexport class FormatSpecHandle implements Disposable {\n private _disposed = false;\n private readonly _provider: FormattingSpecProvider;\n private readonly _koqName: string;\n private readonly _persistenceUnit: string;\n private readonly _system: UnitSystemKey | undefined;\n\n constructor(args: FormatSpecHandleArgs) {\n this._provider = args.provider;\n this._koqName = args.name;\n this._persistenceUnit = args.persistenceUnitName;\n this._system = args.system;\n }\n\n /** The KoQ name this handle is keyed to. */\n public get koqName(): string { return this._koqName; }\n\n /** The persistence unit this handle is keyed to. */\n public get persistenceUnit(): string { return this._persistenceUnit; }\n\n /** The unit system this handle is pinned to, or `undefined` for the active system. */\n public get system(): UnitSystemKey | undefined { return this._system; }\n\n /** The current FormatterSpec, or undefined if not yet loaded. */\n public get formatterSpec(): FormatterSpec | undefined { return this._getEntry()?.formatterSpec; }\n\n /** The current ParserSpec, or undefined if not yet loaded. */\n public get parserSpec(): ParserSpec | undefined { return this._getEntry()?.parserSpec; }\n\n /** Format a quantity value using the current spec.\n * If the formatter is not yet ready, returns `value.toString()` as a fallback.\n * @param value - The numeric value to format.\n * @returns The formatted string.\n */\n public format(value: number): string {\n const formatterSpec = this.formatterSpec;\n if (!formatterSpec)\n return value.toString();\n return this._provider.formatQuantity(value, formatterSpec);\n }\n\n /** Invalidate this handle.\n * Idempotent and safe to call multiple times.\n * No additional teardown is required because the handle owns no external resources.\n */\n public [Symbol.dispose](): void {\n this._disposed = true;\n }\n\n private _getEntry(): FormattingSpecEntry | undefined {\n if (this._disposed)\n return undefined;\n\n return this._provider.getSpecsByNameAndUnit({\n name: this._koqName,\n persistenceUnitName: this._persistenceUnit,\n system: this._system,\n });\n }\n}\n"]}
|
package/lib/cjs/Quantity.d.ts
CHANGED
|
@@ -31,6 +31,8 @@ export declare class Quantity implements QuantityProps {
|
|
|
31
31
|
* @param toUnit The new unit for the quantity.
|
|
32
32
|
* @param conversion Defines the information needed to convert the Quantity's magnitude from the current unit to another unit. This conversion info is usually
|
|
33
33
|
* returned from the UnitsProvider.
|
|
34
|
+
* @throws [[QuantityError]] with [[QuantityStatus.InvalidUnitConversion]] when `conversion.error === true`.
|
|
35
|
+
* @throws [[QuantityError]] with [[QuantityStatus.InvertingZero]] when inversion would require dividing by zero or almost-zero.
|
|
34
36
|
*/
|
|
35
37
|
convertTo(toUnit: UnitProps, conversion: UnitConversionProps): Quantity;
|
|
36
38
|
}
|
|
@@ -42,6 +44,8 @@ export declare class Quantity implements QuantityProps {
|
|
|
42
44
|
export declare function almostZero(value: number): boolean;
|
|
43
45
|
/**
|
|
44
46
|
* Applies a unit conversion to a given value.
|
|
47
|
+
* Does not throw when `props.error === true`; callers are expected to have already handled that contract.
|
|
48
|
+
* For the throwing apply helper, use `UnitConversions.convertValue(...)`.
|
|
45
49
|
* @param value - The value to be converted.
|
|
46
50
|
* @param props - The unit conversion properties.
|
|
47
51
|
* @returns The converted value.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Quantity.d.ts","sourceRoot":"","sources":["../../src/Quantity.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"Quantity.d.ts","sourceRoot":"","sources":["../../src/Quantity.ts"],"names":[],"mappings":"AAIA;;GAEG;AAGH,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG7E;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,GAAE,MAA+B,GAAG,OAAO,CAErG;AAED;;;GAGG;AACH,qBAAa,QAAS,YAAW,aAAa;IAC5C,SAAS,CAAC,UAAU,EAAE,MAAM,CAAO;IACnC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC;IAC3B,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAS;IAEpC,IAAW,IAAI,IAAI,SAAS,CAAuB;IACnD,IAAW,SAAS,IAAI,MAAM,CAA4B;IAC1D,IAAW,OAAO,IAAI,OAAO,CAA0B;IAEvD;;;OAGG;gBACgB,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,MAAM;IAYvD;;;;;;OAMG;IACI,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,mBAAmB,GAAG,QAAQ;CAW/E;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,GAAG,MAAM,CAEjF"}
|
package/lib/cjs/Quantity.js
CHANGED
|
@@ -12,7 +12,7 @@ exports.almostEqual = almostEqual;
|
|
|
12
12
|
exports.almostZero = almostZero;
|
|
13
13
|
exports.applyConversion = applyConversion;
|
|
14
14
|
const Exception_1 = require("./Exception");
|
|
15
|
-
const
|
|
15
|
+
const UnitConversionMath_1 = require("./internal/UnitConversionMath");
|
|
16
16
|
/**
|
|
17
17
|
* Checks if two numbers are approximately equal within given relative tolerance.
|
|
18
18
|
* @param a - The first number to compare.
|
|
@@ -22,9 +22,7 @@ const Interfaces_1 = require("./Interfaces");
|
|
|
22
22
|
* @internal
|
|
23
23
|
*/
|
|
24
24
|
function almostEqual(a, b, tolerance = 2.2204460492503131e-16) {
|
|
25
|
-
|
|
26
|
-
const scaledTolerance = Math.max(1, Math.abs(a), Math.abs(b)) * tolerance;
|
|
27
|
-
return absDiff <= scaledTolerance;
|
|
25
|
+
return (0, UnitConversionMath_1.almostEqual)(a, b, tolerance);
|
|
28
26
|
}
|
|
29
27
|
/** The Quantity class is convenient container to specify both the magnitude and unit of a quantity. This class is commonly
|
|
30
28
|
* returned as the result of parsing a string that represents a quantity.
|
|
@@ -56,45 +54,36 @@ class Quantity {
|
|
|
56
54
|
* @param toUnit The new unit for the quantity.
|
|
57
55
|
* @param conversion Defines the information needed to convert the Quantity's magnitude from the current unit to another unit. This conversion info is usually
|
|
58
56
|
* returned from the UnitsProvider.
|
|
57
|
+
* @throws [[QuantityError]] with [[QuantityStatus.InvalidUnitConversion]] when `conversion.error === true`.
|
|
58
|
+
* @throws [[QuantityError]] with [[QuantityStatus.InvertingZero]] when inversion would require dividing by zero or almost-zero.
|
|
59
59
|
*/
|
|
60
60
|
convertTo(toUnit, conversion) {
|
|
61
|
-
|
|
61
|
+
if (conversion.error) {
|
|
62
|
+
throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvalidUnitConversion, `Cannot convert quantity from "${this.unit.name}" to "${toUnit.name}" using invalid conversion metadata.`);
|
|
63
|
+
}
|
|
64
|
+
const newMagnitude = (0, UnitConversionMath_1.convertValueOrThrow)(this.magnitude, conversion);
|
|
62
65
|
return new Quantity(toUnit, newMagnitude);
|
|
63
66
|
}
|
|
64
67
|
}
|
|
65
68
|
exports.Quantity = Quantity;
|
|
66
|
-
function invert(input) {
|
|
67
|
-
if (almostZero(input)) // mimic the behavior of native here. We don't want to invert those very small values
|
|
68
|
-
throw new Exception_1.QuantityError(Exception_1.QuantityStatus.InvertingZero, "Cannot invert zero value");
|
|
69
|
-
return 1 / input;
|
|
70
|
-
}
|
|
71
69
|
/** Determines if a value is almost zero. (less than 1e-16)
|
|
72
70
|
* @param value - The value to be checked.
|
|
73
71
|
* @returns `true` if the value is almost zero, `false` otherwise.
|
|
74
72
|
* @internal
|
|
75
73
|
*/
|
|
76
74
|
function almostZero(value) {
|
|
77
|
-
return
|
|
75
|
+
return (0, UnitConversionMath_1.almostZero)(value);
|
|
78
76
|
}
|
|
79
77
|
/**
|
|
80
78
|
* Applies a unit conversion to a given value.
|
|
79
|
+
* Does not throw when `props.error === true`; callers are expected to have already handled that contract.
|
|
80
|
+
* For the throwing apply helper, use `UnitConversions.convertValue(...)`.
|
|
81
81
|
* @param value - The value to be converted.
|
|
82
82
|
* @param props - The unit conversion properties.
|
|
83
83
|
* @returns The converted value.
|
|
84
84
|
* @internal
|
|
85
85
|
*/
|
|
86
86
|
function applyConversion(value, props) {
|
|
87
|
-
|
|
88
|
-
// Apply pre-conversion inversion if specified
|
|
89
|
-
if (props.inversion === Interfaces_1.UnitConversionInvert.InvertPreConversion) {
|
|
90
|
-
convertedValue = invert(convertedValue);
|
|
91
|
-
}
|
|
92
|
-
// Apply the conversion factor and offset
|
|
93
|
-
convertedValue = (convertedValue * props.factor) + props.offset;
|
|
94
|
-
// Apply post-conversion inversion if specified
|
|
95
|
-
if (props.inversion === Interfaces_1.UnitConversionInvert.InvertPostConversion) {
|
|
96
|
-
convertedValue = invert(convertedValue);
|
|
97
|
-
}
|
|
98
|
-
return convertedValue;
|
|
87
|
+
return (0, UnitConversionMath_1.applyConversionInternal)(value, props, false);
|
|
99
88
|
}
|
|
100
89
|
//# sourceMappingURL=Quantity.js.map
|
package/lib/cjs/Quantity.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Quantity.js","sourceRoot":"","sources":["../../src/Quantity.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;
|
|
1
|
+
{"version":3,"file":"Quantity.js","sourceRoot":"","sources":["../../src/Quantity.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;AAcH,kCAEC;AAwDD,gCAEC;AAWD,0CAEC;AArFD,2CAA4D;AAE5D,sEAAmK;AAEnK;;;;;;;GAOG;AACH,SAAgB,WAAW,CAAC,CAAS,EAAE,CAAS,EAAE,YAAoB,sBAAsB;IAC1F,OAAO,IAAA,gCAAmB,EAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;AAC9C,CAAC;AAED;;;GAGG;AACH,MAAa,QAAQ;IACT,UAAU,GAAW,GAAG,CAAC;IACzB,KAAK,CAAY;IACjB,QAAQ,GAAY,KAAK,CAAC;IAEpC,IAAW,IAAI,KAAgB,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACnD,IAAW,SAAS,KAAa,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IAC1D,IAAW,OAAO,KAAc,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEvD;;;OAGG;IACH,YAAmB,IAAgB,EAAE,SAAkB;QACrD,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YAClB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,KAAK,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAC/G,CAAC;QAED,IAAI,SAAS,KAAK,SAAS;YACzB,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;IAChC,CAAC;IAED;;;;;;OAMG;IACI,SAAS,CAAC,MAAiB,EAAE,UAA+B;QACjE,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,MAAM,IAAI,yBAAa,CACrB,0BAAc,CAAC,qBAAqB,EACpC,iCAAiC,IAAI,CAAC,IAAI,CAAC,IAAI,SAAS,MAAM,CAAC,IAAI,sCAAsC,CAC1G,CAAC;QACJ,CAAC;QAED,MAAM,YAAY,GAAG,IAAA,wCAAmB,EAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QACrE,OAAO,IAAI,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC5C,CAAC;CACF;AA3CD,4BA2CC;AAED;;;;GAIG;AACH,SAAgB,UAAU,CAAC,KAAa;IACtC,OAAO,IAAA,+BAAkB,EAAC,KAAK,CAAC,CAAC;AACnC,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,eAAe,CAAC,KAAa,EAAE,KAA0B;IACvE,OAAO,IAAA,4CAAuB,EAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AACtD,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Quantity\n */\n\nimport { QuantityError, QuantityStatus } from \"./Exception\";\nimport { QuantityProps, UnitConversionProps, UnitProps } from \"./Interfaces\";\nimport { applyConversionInternal, convertValueOrThrow, almostEqual as internalAlmostEqual, almostZero as internalAlmostZero } from \"./internal/UnitConversionMath\";\n\n/**\n * Checks if two numbers are approximately equal within given relative tolerance.\n * @param a - The first number to compare.\n * @param b - The second number to compare.\n * @param tolerance - Tolerance, scales based on the input number values (multiplied by 1, abs(a) or abs(b), whichever is biggest).\n * @returns True if the numbers are approximately equal, false otherwise.\n * @internal\n */\nexport function almostEqual(a: number, b: number, tolerance: number = 2.2204460492503131e-16): boolean {\n return internalAlmostEqual(a, b, tolerance);\n}\n\n/** The Quantity class is convenient container to specify both the magnitude and unit of a quantity. This class is commonly\n * returned as the result of parsing a string that represents a quantity.\n * @beta\n */\nexport class Quantity implements QuantityProps {\n protected _magnitude: number = 0.0;\n protected _unit: UnitProps;\n protected _isValid: boolean = false;\n\n public get unit(): UnitProps { return this._unit; }\n public get magnitude(): number { return this._magnitude; }\n public get isValid(): boolean { return this._isValid; }\n\n /** Constructor. The Quantity will only be set as valid if a unit is specified.\n * @param unit Defines the quantity's unit.\n * @param magnitude Defines the magnitude of the quantity.\n */\n public constructor(unit?: UnitProps, magnitude?: number) {\n if (undefined !== unit) {\n this._unit = unit;\n this._isValid = true;\n } else {\n this._unit = { name: \"unknown\", label: \"unknown\", phenomenon: \"unknown\", isValid: false, system: \"unknown\" };\n }\n\n if (undefined !== magnitude)\n this._magnitude = magnitude;\n }\n\n /** Convert a Quantity to the specified unit given the UnitConversion.\n * @param toUnit The new unit for the quantity.\n * @param conversion Defines the information needed to convert the Quantity's magnitude from the current unit to another unit. This conversion info is usually\n * returned from the UnitsProvider.\n * @throws [[QuantityError]] with [[QuantityStatus.InvalidUnitConversion]] when `conversion.error === true`.\n * @throws [[QuantityError]] with [[QuantityStatus.InvertingZero]] when inversion would require dividing by zero or almost-zero.\n */\n public convertTo(toUnit: UnitProps, conversion: UnitConversionProps): Quantity {\n if (conversion.error) {\n throw new QuantityError(\n QuantityStatus.InvalidUnitConversion,\n `Cannot convert quantity from \"${this.unit.name}\" to \"${toUnit.name}\" using invalid conversion metadata.`,\n );\n }\n\n const newMagnitude = convertValueOrThrow(this.magnitude, conversion);\n return new Quantity(toUnit, newMagnitude);\n }\n}\n\n/** Determines if a value is almost zero. (less than 1e-16)\n * @param value - The value to be checked.\n * @returns `true` if the value is almost zero, `false` otherwise.\n * @internal\n */\nexport function almostZero(value: number): boolean {\n return internalAlmostZero(value);\n}\n\n/**\n * Applies a unit conversion to a given value.\n * Does not throw when `props.error === true`; callers are expected to have already handled that contract.\n * For the throwing apply helper, use `UnitConversions.convertValue(...)`.\n * @param value - The value to be converted.\n * @param props - The unit conversion properties.\n * @returns The converted value.\n * @internal\n */\nexport function applyConversion(value: number, props: UnitConversionProps): number {\n return applyConversionInternal(value, props, false);\n}\n\n\n"]}
|