@quenty/metricutils 2.4.4 → 2.5.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.
Files changed (64) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +80 -2
  3. package/deploy.nevermore.json +10 -0
  4. package/package.json +22 -4
  5. package/src/Shared/Definitions/MetricUnitDefinitions.lua +1082 -0
  6. package/src/Shared/Definitions/MetricUnitDefinitions.spec.lua +55 -0
  7. package/src/Shared/Definitions/MetricUnitDimensionUtils.lua +164 -0
  8. package/src/Shared/Definitions/MetricUnitDimensionUtils.spec.lua +49 -0
  9. package/src/Shared/Definitions/MetricUnitKinds.lua +237 -0
  10. package/src/Shared/Definitions/MetricUnitKinds.spec.lua +51 -0
  11. package/src/Shared/Formatting/MetricUnitDisplayUnitUtils.lua +129 -0
  12. package/src/Shared/Formatting/MetricUnitFormatUtils.lua +924 -0
  13. package/src/Shared/Formatting/MetricUnitFormatUtils.spec.lua +280 -0
  14. package/src/Shared/Formatting/RxMetricUnitFormatUtils.lua +62 -0
  15. package/src/Shared/Localization/MetricUnitFallbackStrings.lua +289 -0
  16. package/src/Shared/Localization/MetricUnitFallbackStrings.spec.lua +82 -0
  17. package/src/Shared/Localization/MetricUnitTranslator/ar.json.txt +182 -0
  18. package/src/Shared/Localization/MetricUnitTranslator/de.json.txt +182 -0
  19. package/src/Shared/Localization/MetricUnitTranslator/en.json.txt +182 -0
  20. package/src/Shared/Localization/MetricUnitTranslator/es.json.txt +182 -0
  21. package/src/Shared/Localization/MetricUnitTranslator/fr.json.txt +182 -0
  22. package/src/Shared/Localization/MetricUnitTranslator/id.json.txt +182 -0
  23. package/src/Shared/Localization/MetricUnitTranslator/init.lua +92 -0
  24. package/src/Shared/Localization/MetricUnitTranslator/it.json.txt +182 -0
  25. package/src/Shared/Localization/MetricUnitTranslator/ja.json.txt +182 -0
  26. package/src/Shared/Localization/MetricUnitTranslator/ko.json.txt +182 -0
  27. package/src/Shared/Localization/MetricUnitTranslator/pl.json.txt +182 -0
  28. package/src/Shared/Localization/MetricUnitTranslator/pt.json.txt +182 -0
  29. package/src/Shared/Localization/MetricUnitTranslator/ru.json.txt +182 -0
  30. package/src/Shared/Localization/MetricUnitTranslator/th.json.txt +182 -0
  31. package/src/Shared/Localization/MetricUnitTranslator/tr.json.txt +182 -0
  32. package/src/Shared/Localization/MetricUnitTranslator/vi.json.txt +182 -0
  33. package/src/Shared/Localization/MetricUnitTranslator/zh-cn.json.txt +182 -0
  34. package/src/Shared/Localization/MetricUnitTranslator/zh-tw.json.txt +182 -0
  35. package/src/Shared/Localization/MetricUnitTranslator.spec.lua +309 -0
  36. package/src/Shared/Localization/PluralCategoryUtils.lua +103 -0
  37. package/src/Shared/Localization/PluralCategoryUtils.spec.lua +77 -0
  38. package/src/Shared/Logarithmic/DecibelUtils.lua +72 -0
  39. package/src/Shared/Logarithmic/DecibelUtils.spec.lua +35 -0
  40. package/src/Shared/MetricUnit.Angles.spec.lua +80 -0
  41. package/src/Shared/MetricUnit.Customary.spec.lua +104 -0
  42. package/src/Shared/MetricUnit.Derived.spec.lua +173 -0
  43. package/src/Shared/MetricUnit.Display.spec.lua +153 -0
  44. package/src/Shared/MetricUnit.Electrical.spec.lua +114 -0
  45. package/src/Shared/MetricUnit.Math.spec.lua +112 -0
  46. package/src/Shared/MetricUnit.Roblox.spec.lua +34 -0
  47. package/src/Shared/MetricUnit.SI.spec.lua +127 -0
  48. package/src/Shared/MetricUnit.Spring.spec.lua +94 -0
  49. package/src/Shared/MetricUnit.Temperature.spec.lua +212 -0
  50. package/src/Shared/MetricUnit.Time.spec.lua +202 -0
  51. package/src/Shared/MetricUnit.Units.spec.lua +210 -0
  52. package/src/Shared/MetricUnit.lua +1730 -0
  53. package/src/Shared/MetricUnit.spec.lua +362 -0
  54. package/src/Shared/MetricUtils.lua +46 -15
  55. package/src/Shared/MetricUtils.spec.lua +76 -0
  56. package/src/Shared/Parsing/MetricUnitParseUtils.lua +799 -0
  57. package/src/Shared/Parsing/MetricUnitParseUtils.spec.lua +189 -0
  58. package/src/Shared/Systems/MetricUnitSystem.lua +322 -0
  59. package/src/Shared/Systems/MetricUnitSystem.spec.lua +181 -0
  60. package/src/Shared/Systems/MetricUnitSystems.lua +225 -0
  61. package/src/jest.config.lua +3 -0
  62. package/src/node_modules.project.json +7 -0
  63. package/test/default.project.json +25 -0
  64. package/test/scripts/Server/ServerMain.server.lua +14 -0
package/CHANGELOG.md CHANGED
@@ -3,6 +3,12 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [2.5.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/metricutils@2.4.4...@quenty/metricutils@2.5.0) (2026-11-11)
7
+
8
+ ### Features
9
+
10
+ - **metricutils:** add MetricUnit, typed measurements with parsing and localized formatting ([#859](https://github.com/Quenty/NevermoreEngine/issues/859)) ([2ba1298](https://github.com/Quenty/NevermoreEngine/commit/2ba1298f7f226c4e3e04eb3e9bc6f48a1c1a9172))
11
+
6
12
  ## [2.4.4](https://github.com/Quenty/NevermoreEngine/compare/@quenty/metricutils@2.4.3...@quenty/metricutils@2.4.4) (2026-05-30)
7
13
 
8
14
  **Note:** Version bump only for package @quenty/metricutils
package/README.md CHANGED
@@ -11,11 +11,89 @@
11
11
  </a>
12
12
  </div>
13
13
 
14
- Provides ways to convert to or from metric
14
+ Typed, immutable measurements in metric, US customary and Roblox units, with localized formatting
15
15
 
16
- <div align="center"><a href="https://quenty.github.io/NevermoreEngine/api/MetricUtils">View docs →</a></div>
16
+ <div align="center"><a href="https://quenty.github.io/NevermoreEngine/api/MetricUnit">View docs →</a></div>
17
17
 
18
18
  ## Installation
19
19
  ```
20
20
  npm install @quenty/metricutils --save
21
21
  ```
22
+
23
+ ## Usage
24
+
25
+ A `MetricUnit` knows what it measures. Arithmetic checks dimensions, and any unit reads back with `:In`.
26
+
27
+ ```lua
28
+ local MetricUnit = require("MetricUnit")
29
+
30
+ local speed = MetricUnit.kilometers(36) / MetricUnit.hours(1)
31
+ speed:In("meterPerSecond") --> 10
32
+ speed:In("milePerHour") --> 22.369
33
+ speed:GetKind() --> "speed"
34
+
35
+ local energy = MetricUnit.new(2, "kilowatt") * MetricUnit.hours(3)
36
+ energy:In("kilowattHour") --> 6
37
+
38
+ MetricUnit.kilometers(1) + MetricUnit.seconds(1) --> error: cannot add length and time
39
+ ```
40
+
41
+ Roblox values come in through studs, and angles are their own dimension:
42
+
43
+ ```lua
44
+ MetricUnit.fromStudVelocity(part.AssemblyLinearVelocity):In("kilometerPerHour")
45
+ MetricUnit.studs(100):In("meter") --> 28, at Roblox's 28 cm stud
46
+ CFrame.Angles(0, MetricUnit.degrees(90):In("radian"), 0)
47
+ ```
48
+
49
+ Temperatures and points in time are absolute or a difference, so the arithmetic stays honest:
50
+
51
+ ```lua
52
+ (MetricUnit.celsius(15) + MetricUnit.difference(12, "celsius")):In("celsius") --> 27
53
+ MetricUnit.celsius(15) * 2 --> error: cannot multiply an absolute temperature
54
+
55
+ local worldStart = MetricUnit.instant(0)
56
+ local now = worldStart + MetricUnit.years(250)
57
+ (now - worldStart):In("year") --> 250
58
+ ```
59
+
60
+ Format for players in their language. A value shows itself in the system of the unit it was made from; convert it to show another. A locale never chooses the system:
61
+
62
+ ```lua
63
+ MetricUnit.format(MetricUnit.meters(2500)) --> 2.5 km
64
+ MetricUnit.format(MetricUnit.meters(1234.5), { unit = "meter", locale = "de-de" }) --> 1 234,5 m
65
+ MetricUnit.format(MetricUnit.kilometers(5):ToUSCustomary()) --> 3.107 mi
66
+ MetricUnit.format(MetricUnit.new(2, "liter"):ToImperial()) --> 3.52 imp pt
67
+ MetricUnit.format(MetricUnit.minutes(90), { locale = "es-es" }) --> 1 hora, 30 minutos
68
+ MetricUnit.format(MetricUnit.minutes(90), { durationStyle = "clock" }) --> 1:30:00
69
+ ```
70
+
71
+ `MetricUnitTranslator` streams unit names and symbols in 17 languages, one per player, from Unicode CLDR data:
72
+
73
+ ```lua
74
+ local translator = serviceBag:GetService(require("MetricUnitTranslator"))
75
+ MetricUnit.format(MetricUnit.kilometers(5), { translator = translator }) --> 5 км in Russian, 5公里 in Chinese
76
+ ```
77
+
78
+ The translations derive from Unicode CLDR; see the notice in `src/Shared/Localization/MetricUnitTranslator/init.lua`.
79
+
80
+ And read what players type:
81
+
82
+ ```lua
83
+ MetricUnit.parse("1h30m") --> 90 minutes
84
+ MetricUnit.parse("5 m", "time") --> 5 minutes, since a time was expected
85
+ local value, err = MetricUnit.parse(textBox.Text, "length")
86
+ ```
87
+
88
+ Units belong to systems: metric, US customary, British imperial and Roblox are built in, and a game can declare its own, such as studs at another scale:
89
+
90
+ ```lua
91
+ local MINI = MetricUnitSystems.roblox({ name = "robloxMini", metersPerStud = 0.028 })
92
+ local height = MINI:New(5, "stud")
93
+ height:In("meter") --> 0.14
94
+ MetricUnit.format(height) --> 5 studs
95
+ MetricUnitSystems.IMPERIAL:Format(height) --> 5.512 in
96
+ MINI:Parse("5 studs", "length")
97
+ ```
98
+
99
+ `MetricUtils` keeps its plain-number stud conversions at 3.57 studs to the metre, such as `MetricUtils.studsToMeters(357)`.
@@ -0,0 +1,10 @@
1
+ {
2
+ "targets": {
3
+ "test": {
4
+ "universeId": 9716264427,
5
+ "placeId": 128882159252211,
6
+ "project": "test/default.project.json",
7
+ "scriptTemplate": "test/scripts/Server/ServerMain.server.lua"
8
+ }
9
+ }
10
+ }
package/package.json CHANGED
@@ -1,12 +1,19 @@
1
1
  {
2
2
  "name": "@quenty/metricutils",
3
- "version": "2.4.4",
4
- "description": "Provides ways to convert to or from metric",
3
+ "version": "2.5.0",
4
+ "description": "Typed, immutable measurements in metric, US customary and Roblox stud units (time, length, mass, memory, temperature and derived SI units) with localized formatting",
5
5
  "keywords": [
6
6
  "Roblox",
7
7
  "Nevermore",
8
8
  "Lua",
9
- "Metric"
9
+ "Metric",
10
+ "Units",
11
+ "SI",
12
+ "Measurement",
13
+ "Conversion",
14
+ "Localization",
15
+ "Imperial",
16
+ "Studs"
10
17
  ],
11
18
  "bugs": {
12
19
  "url": "https://github.com/Quenty/NevermoreEngine/issues"
@@ -27,8 +34,19 @@
27
34
  "contributors": [
28
35
  "Quenty"
29
36
  ],
37
+ "dependencies": {
38
+ "@quenty/clienttranslator": "14.55.1",
39
+ "@quenty/loader": "10.11.3",
40
+ "@quenty/nevermore-test-runner": "1.6.3",
41
+ "@quenty/rx": "13.35.1",
42
+ "@quenty/time": "2.8.1",
43
+ "@quentystudios/jest-lua": "3.10.0-quenty.2"
44
+ },
45
+ "devDependencies": {
46
+ "@quenty/spring": "10.12.3"
47
+ },
30
48
  "publishConfig": {
31
49
  "access": "public"
32
50
  },
33
- "gitHead": "598b2b62b36bdcbdbbd56f7db10c399831cc6eba"
51
+ "gitHead": "014669a5d6cef7bc42ab007a372d2b2e28352d6e"
34
52
  }