@clayroach/effect 3.19.14-source-capture.6 → 3.19.14-source-capture.8

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 (371) hide show
  1. package/dist/cjs/Utils.js +1 -1
  2. package/dist/cjs/Utils.js.map +1 -1
  3. package/dist/cjs/internal/clock.js +1 -1
  4. package/dist/cjs/internal/clock.js.map +1 -1
  5. package/dist/esm/Utils.js +1 -1
  6. package/dist/esm/Utils.js.map +1 -1
  7. package/dist/esm/internal/clock.js +1 -1
  8. package/dist/esm/internal/clock.js.map +1 -1
  9. package/package.json +1 -1
  10. package/src/Arbitrary.ts +0 -1101
  11. package/src/Array.ts +0 -3589
  12. package/src/BigDecimal.ts +0 -1349
  13. package/src/BigInt.ts +0 -643
  14. package/src/Boolean.ts +0 -287
  15. package/src/Brand.ts +0 -360
  16. package/src/Cache.ts +0 -281
  17. package/src/Cause.ts +0 -1555
  18. package/src/Channel.ts +0 -2355
  19. package/src/ChildExecutorDecision.ts +0 -146
  20. package/src/Chunk.ts +0 -1495
  21. package/src/Clock.ts +0 -111
  22. package/src/Config.ts +0 -542
  23. package/src/ConfigError.ts +0 -270
  24. package/src/ConfigProvider.ts +0 -333
  25. package/src/ConfigProviderPathPatch.ts +0 -100
  26. package/src/Console.ts +0 -226
  27. package/src/Context.ts +0 -585
  28. package/src/Cron.ts +0 -706
  29. package/src/Data.ts +0 -596
  30. package/src/DateTime.ts +0 -1686
  31. package/src/DefaultServices.ts +0 -34
  32. package/src/Deferred.ts +0 -301
  33. package/src/Differ.ts +0 -450
  34. package/src/Duration.ts +0 -1000
  35. package/src/Effect.ts +0 -14839
  36. package/src/Effectable.ts +0 -107
  37. package/src/Either.ts +0 -1040
  38. package/src/Encoding.ts +0 -195
  39. package/src/Equal.ts +0 -98
  40. package/src/Equivalence.ts +0 -235
  41. package/src/ExecutionPlan.ts +0 -308
  42. package/src/ExecutionStrategy.ts +0 -119
  43. package/src/Exit.ts +0 -467
  44. package/src/FastCheck.ts +0 -9
  45. package/src/Fiber.ts +0 -744
  46. package/src/FiberHandle.ts +0 -540
  47. package/src/FiberId.ts +0 -195
  48. package/src/FiberMap.ts +0 -656
  49. package/src/FiberRef.ts +0 -431
  50. package/src/FiberRefs.ts +0 -204
  51. package/src/FiberRefsPatch.ts +0 -105
  52. package/src/FiberSet.ts +0 -491
  53. package/src/FiberStatus.ts +0 -108
  54. package/src/Function.ts +0 -1222
  55. package/src/GlobalValue.ts +0 -53
  56. package/src/Graph.ts +0 -3732
  57. package/src/GroupBy.ts +0 -103
  58. package/src/HKT.ts +0 -45
  59. package/src/Hash.ts +0 -195
  60. package/src/HashMap.ts +0 -519
  61. package/src/HashRing.ts +0 -317
  62. package/src/HashSet.ts +0 -2346
  63. package/src/Inspectable.ts +0 -287
  64. package/src/Iterable.ts +0 -1119
  65. package/src/JSONSchema.ts +0 -1044
  66. package/src/KeyedPool.ts +0 -167
  67. package/src/Layer.ts +0 -1251
  68. package/src/LayerMap.ts +0 -436
  69. package/src/List.ts +0 -977
  70. package/src/LogLevel.ts +0 -285
  71. package/src/LogSpan.ts +0 -25
  72. package/src/Logger.ts +0 -702
  73. package/src/Mailbox.ts +0 -268
  74. package/src/ManagedRuntime.ts +0 -180
  75. package/src/Match.ts +0 -1477
  76. package/src/MergeDecision.ts +0 -95
  77. package/src/MergeState.ts +0 -172
  78. package/src/MergeStrategy.ts +0 -107
  79. package/src/Metric.ts +0 -780
  80. package/src/MetricBoundaries.ts +0 -69
  81. package/src/MetricHook.ts +0 -151
  82. package/src/MetricKey.ts +0 -224
  83. package/src/MetricKeyType.ts +0 -262
  84. package/src/MetricLabel.ts +0 -47
  85. package/src/MetricPair.ts +0 -71
  86. package/src/MetricPolling.ts +0 -148
  87. package/src/MetricRegistry.ts +0 -48
  88. package/src/MetricState.ts +0 -257
  89. package/src/Micro.ts +0 -4405
  90. package/src/ModuleVersion.ts +0 -18
  91. package/src/MutableHashMap.ts +0 -411
  92. package/src/MutableHashSet.ts +0 -706
  93. package/src/MutableList.ts +0 -297
  94. package/src/MutableQueue.ts +0 -227
  95. package/src/MutableRef.ts +0 -202
  96. package/src/NonEmptyIterable.ts +0 -32
  97. package/src/Number.ts +0 -1071
  98. package/src/Option.ts +0 -2170
  99. package/src/Order.ts +0 -373
  100. package/src/Ordering.ts +0 -111
  101. package/src/ParseResult.ts +0 -2031
  102. package/src/PartitionedSemaphore.ts +0 -200
  103. package/src/Pipeable.ts +0 -566
  104. package/src/Pool.ts +0 -204
  105. package/src/Predicate.ts +0 -1405
  106. package/src/Pretty.ts +0 -205
  107. package/src/PrimaryKey.ts +0 -23
  108. package/src/PubSub.ts +0 -182
  109. package/src/Queue.ts +0 -644
  110. package/src/Random.ts +0 -204
  111. package/src/RateLimiter.ts +0 -138
  112. package/src/RcMap.ts +0 -141
  113. package/src/RcRef.ts +0 -122
  114. package/src/Readable.ts +0 -93
  115. package/src/Record.ts +0 -1274
  116. package/src/RedBlackTree.ts +0 -421
  117. package/src/Redacted.ts +0 -144
  118. package/src/Ref.ts +0 -180
  119. package/src/RegExp.ts +0 -38
  120. package/src/Reloadable.ts +0 -127
  121. package/src/Request.ts +0 -347
  122. package/src/RequestBlock.ts +0 -118
  123. package/src/RequestResolver.ts +0 -366
  124. package/src/Resource.ts +0 -119
  125. package/src/Runtime.ts +0 -383
  126. package/src/RuntimeFlags.ts +0 -368
  127. package/src/RuntimeFlagsPatch.ts +0 -183
  128. package/src/STM.ts +0 -2045
  129. package/src/Schedule.ts +0 -2219
  130. package/src/ScheduleDecision.ts +0 -62
  131. package/src/ScheduleInterval.ts +0 -151
  132. package/src/ScheduleIntervals.ts +0 -122
  133. package/src/Scheduler.ts +0 -353
  134. package/src/Schema.ts +0 -10914
  135. package/src/SchemaAST.ts +0 -3043
  136. package/src/Scope.ts +0 -204
  137. package/src/ScopedCache.ts +0 -151
  138. package/src/ScopedRef.ts +0 -117
  139. package/src/Secret.ts +0 -88
  140. package/src/SingleProducerAsyncInput.ts +0 -67
  141. package/src/Sink.ts +0 -1461
  142. package/src/SortedMap.ts +0 -287
  143. package/src/SortedSet.ts +0 -390
  144. package/src/Stream.ts +0 -6468
  145. package/src/StreamEmit.ts +0 -136
  146. package/src/StreamHaltStrategy.ts +0 -123
  147. package/src/Streamable.ts +0 -45
  148. package/src/String.ts +0 -778
  149. package/src/Struct.ts +0 -243
  150. package/src/Subscribable.ts +0 -100
  151. package/src/SubscriptionRef.ts +0 -298
  152. package/src/Supervisor.ts +0 -240
  153. package/src/Symbol.ts +0 -29
  154. package/src/SynchronizedRef.ts +0 -270
  155. package/src/TArray.ts +0 -495
  156. package/src/TDeferred.ts +0 -100
  157. package/src/TMap.ts +0 -515
  158. package/src/TPriorityQueue.ts +0 -223
  159. package/src/TPubSub.ts +0 -200
  160. package/src/TQueue.ts +0 -432
  161. package/src/TRandom.ts +0 -129
  162. package/src/TReentrantLock.ts +0 -224
  163. package/src/TRef.ts +0 -178
  164. package/src/TSemaphore.ts +0 -129
  165. package/src/TSet.ts +0 -365
  166. package/src/TSubscriptionRef.ts +0 -192
  167. package/src/Take.ts +0 -258
  168. package/src/TestAnnotation.ts +0 -158
  169. package/src/TestAnnotationMap.ts +0 -119
  170. package/src/TestAnnotations.ts +0 -117
  171. package/src/TestClock.ts +0 -556
  172. package/src/TestConfig.ts +0 -47
  173. package/src/TestContext.ts +0 -36
  174. package/src/TestLive.ts +0 -53
  175. package/src/TestServices.ts +0 -390
  176. package/src/TestSized.ts +0 -55
  177. package/src/Tracer.ts +0 -198
  178. package/src/Trie.ts +0 -840
  179. package/src/Tuple.ts +0 -305
  180. package/src/Types.ts +0 -353
  181. package/src/Unify.ts +0 -113
  182. package/src/UpstreamPullRequest.ts +0 -117
  183. package/src/UpstreamPullStrategy.ts +0 -121
  184. package/src/Utils.ts +0 -809
  185. package/src/index.ts +0 -1561
  186. package/src/internal/array.ts +0 -8
  187. package/src/internal/blockedRequests.ts +0 -520
  188. package/src/internal/cache.ts +0 -733
  189. package/src/internal/cause.ts +0 -1050
  190. package/src/internal/channel/channelExecutor.ts +0 -1200
  191. package/src/internal/channel/channelState.ts +0 -134
  192. package/src/internal/channel/childExecutorDecision.ts +0 -96
  193. package/src/internal/channel/continuation.ts +0 -200
  194. package/src/internal/channel/mergeDecision.ts +0 -113
  195. package/src/internal/channel/mergeState.ts +0 -120
  196. package/src/internal/channel/mergeStrategy.ts +0 -72
  197. package/src/internal/channel/singleProducerAsyncInput.ts +0 -259
  198. package/src/internal/channel/subexecutor.ts +0 -229
  199. package/src/internal/channel/upstreamPullRequest.ts +0 -84
  200. package/src/internal/channel/upstreamPullStrategy.ts +0 -87
  201. package/src/internal/channel.ts +0 -2603
  202. package/src/internal/clock.ts +0 -95
  203. package/src/internal/completedRequestMap.ts +0 -9
  204. package/src/internal/concurrency.ts +0 -54
  205. package/src/internal/config.ts +0 -716
  206. package/src/internal/configError.ts +0 -304
  207. package/src/internal/configProvider/pathPatch.ts +0 -97
  208. package/src/internal/configProvider.ts +0 -799
  209. package/src/internal/console.ts +0 -153
  210. package/src/internal/context.ts +0 -337
  211. package/src/internal/core-effect.ts +0 -2293
  212. package/src/internal/core-stream.ts +0 -998
  213. package/src/internal/core.ts +0 -3273
  214. package/src/internal/data.ts +0 -36
  215. package/src/internal/dataSource.ts +0 -327
  216. package/src/internal/dateTime.ts +0 -1277
  217. package/src/internal/defaultServices/console.ts +0 -100
  218. package/src/internal/defaultServices.ts +0 -163
  219. package/src/internal/deferred.ts +0 -46
  220. package/src/internal/differ/chunkPatch.ts +0 -211
  221. package/src/internal/differ/contextPatch.ts +0 -232
  222. package/src/internal/differ/hashMapPatch.ts +0 -220
  223. package/src/internal/differ/hashSetPatch.ts +0 -176
  224. package/src/internal/differ/orPatch.ts +0 -311
  225. package/src/internal/differ/readonlyArrayPatch.ts +0 -210
  226. package/src/internal/differ.ts +0 -200
  227. package/src/internal/doNotation.ts +0 -80
  228. package/src/internal/effect/circular.ts +0 -905
  229. package/src/internal/effectable.ts +0 -131
  230. package/src/internal/either.ts +0 -110
  231. package/src/internal/encoding/base64.ts +0 -286
  232. package/src/internal/encoding/base64Url.ts +0 -29
  233. package/src/internal/encoding/common.ts +0 -51
  234. package/src/internal/encoding/hex.ts +0 -315
  235. package/src/internal/errors.ts +0 -7
  236. package/src/internal/executionPlan.ts +0 -114
  237. package/src/internal/executionStrategy.ts +0 -74
  238. package/src/internal/fiber.ts +0 -388
  239. package/src/internal/fiberId.ts +0 -267
  240. package/src/internal/fiberMessage.ts +0 -82
  241. package/src/internal/fiberRefs/patch.ts +0 -144
  242. package/src/internal/fiberRefs.ts +0 -297
  243. package/src/internal/fiberRuntime.ts +0 -3915
  244. package/src/internal/fiberScope.ts +0 -71
  245. package/src/internal/fiberStatus.ts +0 -119
  246. package/src/internal/groupBy.ts +0 -530
  247. package/src/internal/hashMap/array.ts +0 -49
  248. package/src/internal/hashMap/bitwise.ts +0 -32
  249. package/src/internal/hashMap/config.ts +0 -14
  250. package/src/internal/hashMap/keySet.ts +0 -8
  251. package/src/internal/hashMap/node.ts +0 -391
  252. package/src/internal/hashMap.ts +0 -586
  253. package/src/internal/hashSet.ts +0 -323
  254. package/src/internal/keyedPool.ts +0 -244
  255. package/src/internal/layer/circular.ts +0 -228
  256. package/src/internal/layer.ts +0 -1487
  257. package/src/internal/logSpan.ts +0 -20
  258. package/src/internal/logger-circular.ts +0 -24
  259. package/src/internal/logger.ts +0 -485
  260. package/src/internal/mailbox.ts +0 -561
  261. package/src/internal/managedRuntime/circular.ts +0 -6
  262. package/src/internal/managedRuntime.ts +0 -134
  263. package/src/internal/matcher.ts +0 -652
  264. package/src/internal/metric/boundaries.ts +0 -75
  265. package/src/internal/metric/hook.ts +0 -483
  266. package/src/internal/metric/key.ts +0 -167
  267. package/src/internal/metric/keyType.ts +0 -238
  268. package/src/internal/metric/label.ts +0 -41
  269. package/src/internal/metric/pair.ts +0 -48
  270. package/src/internal/metric/polling.ts +0 -149
  271. package/src/internal/metric/registry.ts +0 -187
  272. package/src/internal/metric/state.ts +0 -290
  273. package/src/internal/metric.ts +0 -577
  274. package/src/internal/opCodes/cause.ts +0 -35
  275. package/src/internal/opCodes/channel.ts +0 -83
  276. package/src/internal/opCodes/channelChildExecutorDecision.ts +0 -17
  277. package/src/internal/opCodes/channelMergeDecision.ts +0 -11
  278. package/src/internal/opCodes/channelMergeState.ts +0 -17
  279. package/src/internal/opCodes/channelMergeStrategy.ts +0 -11
  280. package/src/internal/opCodes/channelState.ts +0 -23
  281. package/src/internal/opCodes/channelUpstreamPullRequest.ts +0 -11
  282. package/src/internal/opCodes/channelUpstreamPullStrategy.ts +0 -11
  283. package/src/internal/opCodes/config.ts +0 -65
  284. package/src/internal/opCodes/configError.ts +0 -35
  285. package/src/internal/opCodes/continuation.ts +0 -11
  286. package/src/internal/opCodes/deferred.ts +0 -11
  287. package/src/internal/opCodes/effect.ts +0 -89
  288. package/src/internal/opCodes/layer.ts +0 -59
  289. package/src/internal/opCodes/streamHaltStrategy.ts +0 -23
  290. package/src/internal/option.ts +0 -80
  291. package/src/internal/pool.ts +0 -432
  292. package/src/internal/pubsub.ts +0 -1762
  293. package/src/internal/query.ts +0 -204
  294. package/src/internal/queue.ts +0 -766
  295. package/src/internal/random.ts +0 -161
  296. package/src/internal/rateLimiter.ts +0 -93
  297. package/src/internal/rcMap.ts +0 -285
  298. package/src/internal/rcRef.ts +0 -192
  299. package/src/internal/redBlackTree/iterator.ts +0 -200
  300. package/src/internal/redBlackTree/node.ts +0 -68
  301. package/src/internal/redBlackTree.ts +0 -1245
  302. package/src/internal/redacted.ts +0 -73
  303. package/src/internal/ref.ts +0 -171
  304. package/src/internal/reloadable.ts +0 -140
  305. package/src/internal/request.ts +0 -177
  306. package/src/internal/resource.ts +0 -76
  307. package/src/internal/ringBuffer.ts +0 -68
  308. package/src/internal/runtime.ts +0 -558
  309. package/src/internal/runtimeFlags.ts +0 -188
  310. package/src/internal/runtimeFlagsPatch.ts +0 -103
  311. package/src/internal/schedule/decision.ts +0 -47
  312. package/src/internal/schedule/interval.ts +0 -101
  313. package/src/internal/schedule/intervals.ts +0 -180
  314. package/src/internal/schedule.ts +0 -2199
  315. package/src/internal/schema/errors.ts +0 -191
  316. package/src/internal/schema/schemaId.ts +0 -106
  317. package/src/internal/schema/util.ts +0 -50
  318. package/src/internal/scopedCache.ts +0 -644
  319. package/src/internal/scopedRef.ts +0 -118
  320. package/src/internal/secret.ts +0 -89
  321. package/src/internal/singleShotGen.ts +0 -35
  322. package/src/internal/sink.ts +0 -2120
  323. package/src/internal/stack.ts +0 -10
  324. package/src/internal/stm/core.ts +0 -817
  325. package/src/internal/stm/entry.ts +0 -59
  326. package/src/internal/stm/journal.ts +0 -123
  327. package/src/internal/stm/opCodes/stm.ts +0 -71
  328. package/src/internal/stm/opCodes/stmState.ts +0 -17
  329. package/src/internal/stm/opCodes/strategy.ts +0 -17
  330. package/src/internal/stm/opCodes/tExit.ts +0 -29
  331. package/src/internal/stm/opCodes/tryCommit.ts +0 -11
  332. package/src/internal/stm/stm.ts +0 -1453
  333. package/src/internal/stm/stmState.ts +0 -136
  334. package/src/internal/stm/tArray.ts +0 -550
  335. package/src/internal/stm/tDeferred.ts +0 -81
  336. package/src/internal/stm/tExit.ts +0 -190
  337. package/src/internal/stm/tMap.ts +0 -824
  338. package/src/internal/stm/tPriorityQueue.ts +0 -267
  339. package/src/internal/stm/tPubSub.ts +0 -551
  340. package/src/internal/stm/tQueue.ts +0 -393
  341. package/src/internal/stm/tRandom.ts +0 -140
  342. package/src/internal/stm/tReentrantLock.ts +0 -352
  343. package/src/internal/stm/tRef.ts +0 -195
  344. package/src/internal/stm/tSemaphore.ts +0 -113
  345. package/src/internal/stm/tSet.ts +0 -259
  346. package/src/internal/stm/tSubscriptionRef.ts +0 -286
  347. package/src/internal/stm/tryCommit.ts +0 -34
  348. package/src/internal/stm/txnId.ts +0 -14
  349. package/src/internal/stm/versioned.ts +0 -4
  350. package/src/internal/stream/debounceState.ts +0 -57
  351. package/src/internal/stream/emit.ts +0 -123
  352. package/src/internal/stream/haltStrategy.ts +0 -94
  353. package/src/internal/stream/handoff.ts +0 -187
  354. package/src/internal/stream/handoffSignal.ts +0 -59
  355. package/src/internal/stream/pull.ts +0 -34
  356. package/src/internal/stream/sinkEndReason.ts +0 -30
  357. package/src/internal/stream/zipAllState.ts +0 -88
  358. package/src/internal/stream/zipChunksState.ts +0 -56
  359. package/src/internal/stream.ts +0 -8801
  360. package/src/internal/string-utils.ts +0 -107
  361. package/src/internal/subscriptionRef.ts +0 -138
  362. package/src/internal/supervisor/patch.ts +0 -190
  363. package/src/internal/supervisor.ts +0 -303
  364. package/src/internal/synchronizedRef.ts +0 -114
  365. package/src/internal/take.ts +0 -199
  366. package/src/internal/testing/sleep.ts +0 -27
  367. package/src/internal/testing/suspendedWarningData.ts +0 -85
  368. package/src/internal/testing/warningData.ts +0 -94
  369. package/src/internal/tracer.ts +0 -293
  370. package/src/internal/trie.ts +0 -722
  371. package/src/internal/version.ts +0 -7
package/src/BigDecimal.ts DELETED
@@ -1,1349 +0,0 @@
1
- /**
2
- * This module provides utility functions and type class instances for working with the `BigDecimal` type in TypeScript.
3
- * It includes functions for basic arithmetic operations, as well as type class instances for `Equivalence` and `Order`.
4
- *
5
- * A `BigDecimal` allows storing any real number to arbitrary precision; which avoids common floating point errors
6
- * (such as 0.1 + 0.2 ≠ 0.3) at the cost of complexity.
7
- *
8
- * Internally, `BigDecimal` uses a `BigInt` object, paired with a 64-bit integer which determines the position of the
9
- * decimal point. Therefore, the precision *is not* actually arbitrary, but limited to 2<sup>63</sup> decimal places.
10
- *
11
- * It is not recommended to convert a floating point number to a decimal directly, as the floating point representation
12
- * may be unexpected.
13
- *
14
- * @module BigDecimal
15
- * @since 2.0.0
16
- * @see {@link module:BigInt} for more similar operations on `bigint` types
17
- * @see {@link module:Number} for more similar operations on `number` types
18
- */
19
-
20
- import * as Equal from "./Equal.js"
21
- import * as equivalence from "./Equivalence.js"
22
- import { dual, pipe } from "./Function.js"
23
- import * as Hash from "./Hash.js"
24
- import { type Inspectable, NodeInspectSymbol } from "./Inspectable.js"
25
- import * as Option from "./Option.js"
26
- import * as order from "./Order.js"
27
- import type { Ordering } from "./Ordering.js"
28
- import { type Pipeable, pipeArguments } from "./Pipeable.js"
29
- import { hasProperty } from "./Predicate.js"
30
-
31
- const DEFAULT_PRECISION = 100
32
- const FINITE_INT_REGEX = /^[+-]?\d+$/
33
-
34
- /**
35
- * @since 2.0.0
36
- * @category symbols
37
- */
38
- export const TypeId: unique symbol = Symbol.for("effect/BigDecimal")
39
-
40
- /**
41
- * @since 2.0.0
42
- * @category symbol
43
- */
44
- export type TypeId = typeof TypeId
45
-
46
- /**
47
- * @since 2.0.0
48
- * @category models
49
- */
50
- export interface BigDecimal extends Equal.Equal, Pipeable, Inspectable {
51
- readonly [TypeId]: TypeId
52
- readonly value: bigint
53
- readonly scale: number
54
- /** @internal */
55
- normalized?: BigDecimal
56
- }
57
-
58
- const BigDecimalProto: Omit<BigDecimal, "value" | "scale" | "normalized"> = {
59
- [TypeId]: TypeId,
60
- [Hash.symbol](this: BigDecimal): number {
61
- const normalized = normalize(this)
62
- return pipe(
63
- Hash.hash(normalized.value),
64
- Hash.combine(Hash.number(normalized.scale)),
65
- Hash.cached(this)
66
- )
67
- },
68
- [Equal.symbol](this: BigDecimal, that: unknown): boolean {
69
- return isBigDecimal(that) && equals(this, that)
70
- },
71
- toString(this: BigDecimal) {
72
- return `BigDecimal(${format(this)})`
73
- },
74
- toJSON(this: BigDecimal) {
75
- return {
76
- _id: "BigDecimal",
77
- value: String(this.value),
78
- scale: this.scale
79
- }
80
- },
81
- [NodeInspectSymbol](this: BigDecimal) {
82
- return this.toJSON()
83
- },
84
- pipe() {
85
- return pipeArguments(this, arguments)
86
- }
87
- } as const
88
-
89
- /**
90
- * Checks if a given value is a `BigDecimal`.
91
- *
92
- * @since 2.0.0
93
- * @category guards
94
- */
95
- export const isBigDecimal = (u: unknown): u is BigDecimal => hasProperty(u, TypeId)
96
-
97
- /**
98
- * Creates a `BigDecimal` from a `bigint` value and a scale.
99
- *
100
- * @since 2.0.0
101
- * @category constructors
102
- */
103
- export const make = (value: bigint, scale: number): BigDecimal => {
104
- const o = Object.create(BigDecimalProto)
105
- o.value = value
106
- o.scale = scale
107
- return o
108
- }
109
-
110
- /**
111
- * Internal function used to create pre-normalized `BigDecimal`s.
112
- *
113
- * @internal
114
- */
115
- export const unsafeMakeNormalized = (value: bigint, scale: number): BigDecimal => {
116
- if (value !== bigint0 && value % bigint10 === bigint0) {
117
- throw new RangeError("Value must be normalized")
118
- }
119
-
120
- const o = make(value, scale)
121
- o.normalized = o
122
- return o
123
- }
124
-
125
- const bigint0 = BigInt(0)
126
- const bigint1 = BigInt(1)
127
- const bigint10 = BigInt(10)
128
- const zero = unsafeMakeNormalized(bigint0, 0)
129
-
130
- /**
131
- * Normalizes a given `BigDecimal` by removing trailing zeros.
132
- *
133
- * **Example**
134
- *
135
- * ```ts
136
- * import * as assert from "node:assert"
137
- * import { normalize, make, unsafeFromString } from "effect/BigDecimal"
138
- *
139
- * assert.deepStrictEqual(normalize(unsafeFromString("123.00000")), normalize(make(123n, 0)))
140
- * assert.deepStrictEqual(normalize(unsafeFromString("12300000")), normalize(make(123n, -5)))
141
- * ```
142
- *
143
- * @since 2.0.0
144
- * @category scaling
145
- */
146
- export const normalize = (self: BigDecimal): BigDecimal => {
147
- if (self.normalized === undefined) {
148
- if (self.value === bigint0) {
149
- self.normalized = zero
150
- } else {
151
- const digits = `${self.value}`
152
-
153
- let trail = 0
154
- for (let i = digits.length - 1; i >= 0; i--) {
155
- if (digits[i] === "0") {
156
- trail++
157
- } else {
158
- break
159
- }
160
- }
161
-
162
- if (trail === 0) {
163
- self.normalized = self
164
- }
165
-
166
- const value = BigInt(digits.substring(0, digits.length - trail))
167
- const scale = self.scale - trail
168
- self.normalized = unsafeMakeNormalized(value, scale)
169
- }
170
- }
171
-
172
- return self.normalized
173
- }
174
-
175
- /**
176
- * Scales a given `BigDecimal` to the specified scale.
177
- *
178
- * If the given scale is smaller than the current scale, the value will be rounded down to
179
- * the nearest integer.
180
- *
181
- * @since 2.0.0
182
- * @category scaling
183
- */
184
- export const scale: {
185
- (scale: number): (self: BigDecimal) => BigDecimal
186
- (self: BigDecimal, scale: number): BigDecimal
187
- } = dual(2, (self: BigDecimal, scale: number): BigDecimal => {
188
- if (scale > self.scale) {
189
- return make(self.value * bigint10 ** BigInt(scale - self.scale), scale)
190
- }
191
-
192
- if (scale < self.scale) {
193
- return make(self.value / bigint10 ** BigInt(self.scale - scale), scale)
194
- }
195
-
196
- return self
197
- })
198
-
199
- /**
200
- * Provides an addition operation on `BigDecimal`s.
201
- *
202
- * @example
203
- * ```ts
204
- * import * as assert from "node:assert"
205
- * import { sum, unsafeFromString } from "effect/BigDecimal"
206
- *
207
- * assert.deepStrictEqual(sum(unsafeFromString("2"), unsafeFromString("3")), unsafeFromString("5"))
208
- * ```
209
- *
210
- * @since 2.0.0
211
- * @category math
212
- */
213
- export const sum: {
214
- (that: BigDecimal): (self: BigDecimal) => BigDecimal
215
- (self: BigDecimal, that: BigDecimal): BigDecimal
216
- } = dual(2, (self: BigDecimal, that: BigDecimal): BigDecimal => {
217
- if (that.value === bigint0) {
218
- return self
219
- }
220
-
221
- if (self.value === bigint0) {
222
- return that
223
- }
224
-
225
- if (self.scale > that.scale) {
226
- return make(scale(that, self.scale).value + self.value, self.scale)
227
- }
228
-
229
- if (self.scale < that.scale) {
230
- return make(scale(self, that.scale).value + that.value, that.scale)
231
- }
232
-
233
- return make(self.value + that.value, self.scale)
234
- })
235
-
236
- /**
237
- * Provides a multiplication operation on `BigDecimal`s.
238
- *
239
- * @example
240
- * ```ts
241
- * import * as assert from "node:assert"
242
- * import { multiply, unsafeFromString } from "effect/BigDecimal"
243
- *
244
- * assert.deepStrictEqual(multiply(unsafeFromString("2"), unsafeFromString("3")), unsafeFromString("6"))
245
- * ```
246
- *
247
- * @since 2.0.0
248
- * @category math
249
- */
250
- export const multiply: {
251
- (that: BigDecimal): (self: BigDecimal) => BigDecimal
252
- (self: BigDecimal, that: BigDecimal): BigDecimal
253
- } = dual(2, (self: BigDecimal, that: BigDecimal): BigDecimal => {
254
- if (that.value === bigint0 || self.value === bigint0) {
255
- return zero
256
- }
257
-
258
- return make(self.value * that.value, self.scale + that.scale)
259
- })
260
-
261
- /**
262
- * Provides a subtraction operation on `BigDecimal`s.
263
- *
264
- * @example
265
- * ```ts
266
- * import * as assert from "node:assert"
267
- * import { subtract, unsafeFromString } from "effect/BigDecimal"
268
- *
269
- * assert.deepStrictEqual(subtract(unsafeFromString("2"), unsafeFromString("3")), unsafeFromString("-1"))
270
- * ```
271
- *
272
- * @since 2.0.0
273
- * @category math
274
- */
275
- export const subtract: {
276
- (that: BigDecimal): (self: BigDecimal) => BigDecimal
277
- (self: BigDecimal, that: BigDecimal): BigDecimal
278
- } = dual(2, (self: BigDecimal, that: BigDecimal): BigDecimal => {
279
- if (that.value === bigint0) {
280
- return self
281
- }
282
-
283
- if (self.value === bigint0) {
284
- return make(-that.value, that.scale)
285
- }
286
-
287
- if (self.scale > that.scale) {
288
- return make(self.value - scale(that, self.scale).value, self.scale)
289
- }
290
-
291
- if (self.scale < that.scale) {
292
- return make(scale(self, that.scale).value - that.value, that.scale)
293
- }
294
-
295
- return make(self.value - that.value, self.scale)
296
- })
297
-
298
- /**
299
- * Internal function used for arbitrary precision division.
300
- */
301
- const divideWithPrecision = (
302
- num: bigint,
303
- den: bigint,
304
- scale: number,
305
- precision: number
306
- ): BigDecimal => {
307
- const numNegative = num < bigint0
308
- const denNegative = den < bigint0
309
- const negateResult = numNegative !== denNegative
310
-
311
- num = numNegative ? -num : num
312
- den = denNegative ? -den : den
313
-
314
- // Shift digits until numerator is larger than denominator (set scale appropriately).
315
- while (num < den) {
316
- num *= bigint10
317
- scale++
318
- }
319
-
320
- // First division.
321
- let quotient = num / den
322
- let remainder = num % den
323
-
324
- if (remainder === bigint0) {
325
- // No remainder, return immediately.
326
- return make(negateResult ? -quotient : quotient, scale)
327
- }
328
-
329
- // The quotient is guaranteed to be non-negative at this point. No need to consider sign.
330
- let count = `${quotient}`.length
331
-
332
- // Shift the remainder by 1 decimal; The quotient will be 1 digit upon next division.
333
- remainder *= bigint10
334
- while (remainder !== bigint0 && count < precision) {
335
- const q = remainder / den
336
- const r = remainder % den
337
- quotient = quotient * bigint10 + q
338
- remainder = r * bigint10
339
-
340
- count++
341
- scale++
342
- }
343
-
344
- if (remainder !== bigint0) {
345
- // Round final number with remainder.
346
- quotient += roundTerminal(remainder / den)
347
- }
348
-
349
- return make(negateResult ? -quotient : quotient, scale)
350
- }
351
-
352
- /**
353
- * Internal function used for rounding.
354
- *
355
- * Returns 1 if the most significant digit is >= 5, otherwise 0.
356
- *
357
- * This is used after dividing a number by a power of ten and rounding the last digit.
358
- *
359
- * @internal
360
- */
361
- export const roundTerminal = (n: bigint): bigint => {
362
- const pos = n >= bigint0 ? 0 : 1
363
- return Number(`${n}`[pos]) < 5 ? bigint0 : bigint1
364
- }
365
-
366
- /**
367
- * Provides a division operation on `BigDecimal`s.
368
- *
369
- * If the dividend is not a multiple of the divisor the result will be a `BigDecimal` value
370
- * which represents the integer division rounded down to the nearest integer.
371
- *
372
- * If the divisor is `0`, the result will be `None`.
373
- *
374
- * @example
375
- * ```ts
376
- * import * as assert from "node:assert"
377
- * import { BigDecimal, Option } from "effect"
378
- *
379
- * assert.deepStrictEqual(BigDecimal.divide(BigDecimal.unsafeFromString("6"), BigDecimal.unsafeFromString("3")), Option.some(BigDecimal.unsafeFromString("2")))
380
- * assert.deepStrictEqual(BigDecimal.divide(BigDecimal.unsafeFromString("6"), BigDecimal.unsafeFromString("4")), Option.some(BigDecimal.unsafeFromString("1.5")))
381
- * assert.deepStrictEqual(BigDecimal.divide(BigDecimal.unsafeFromString("6"), BigDecimal.unsafeFromString("0")), Option.none())
382
- * ```
383
- *
384
- * @since 2.0.0
385
- * @category math
386
- */
387
- export const divide: {
388
- (that: BigDecimal): (self: BigDecimal) => Option.Option<BigDecimal>
389
- (self: BigDecimal, that: BigDecimal): Option.Option<BigDecimal>
390
- } = dual(2, (self: BigDecimal, that: BigDecimal): Option.Option<BigDecimal> => {
391
- if (that.value === bigint0) {
392
- return Option.none()
393
- }
394
-
395
- if (self.value === bigint0) {
396
- return Option.some(zero)
397
- }
398
-
399
- const scale = self.scale - that.scale
400
- if (self.value === that.value) {
401
- return Option.some(make(bigint1, scale))
402
- }
403
-
404
- return Option.some(divideWithPrecision(self.value, that.value, scale, DEFAULT_PRECISION))
405
- })
406
-
407
- /**
408
- * Provides an unsafe division operation on `BigDecimal`s.
409
- *
410
- * If the dividend is not a multiple of the divisor the result will be a `BigDecimal` value
411
- * which represents the integer division rounded down to the nearest integer.
412
- *
413
- * Throws a `RangeError` if the divisor is `0`.
414
- *
415
- * @example
416
- * ```ts
417
- * import * as assert from "node:assert"
418
- * import { unsafeDivide, unsafeFromString } from "effect/BigDecimal"
419
- *
420
- * assert.deepStrictEqual(unsafeDivide(unsafeFromString("6"), unsafeFromString("3")), unsafeFromString("2"))
421
- * assert.deepStrictEqual(unsafeDivide(unsafeFromString("6"), unsafeFromString("4")), unsafeFromString("1.5"))
422
- * ```
423
- *
424
- * @since 2.0.0
425
- * @category math
426
- */
427
- export const unsafeDivide: {
428
- (that: BigDecimal): (self: BigDecimal) => BigDecimal
429
- (self: BigDecimal, that: BigDecimal): BigDecimal
430
- } = dual(2, (self: BigDecimal, that: BigDecimal): BigDecimal => {
431
- if (that.value === bigint0) {
432
- throw new RangeError("Division by zero")
433
- }
434
-
435
- if (self.value === bigint0) {
436
- return zero
437
- }
438
-
439
- const scale = self.scale - that.scale
440
- if (self.value === that.value) {
441
- return make(bigint1, scale)
442
- }
443
- return divideWithPrecision(self.value, that.value, scale, DEFAULT_PRECISION)
444
- })
445
-
446
- /**
447
- * @since 2.0.0
448
- * @category instances
449
- */
450
- export const Order: order.Order<BigDecimal> = order.make((self, that) => {
451
- const scmp = order.number(sign(self), sign(that))
452
- if (scmp !== 0) {
453
- return scmp
454
- }
455
-
456
- if (self.scale > that.scale) {
457
- return order.bigint(self.value, scale(that, self.scale).value)
458
- }
459
-
460
- if (self.scale < that.scale) {
461
- return order.bigint(scale(self, that.scale).value, that.value)
462
- }
463
-
464
- return order.bigint(self.value, that.value)
465
- })
466
-
467
- /**
468
- * Returns `true` if the first argument is less than the second, otherwise `false`.
469
- *
470
- * @example
471
- * ```ts
472
- * import * as assert from "node:assert"
473
- * import { lessThan, unsafeFromString } from "effect/BigDecimal"
474
- *
475
- * assert.deepStrictEqual(lessThan(unsafeFromString("2"), unsafeFromString("3")), true)
476
- * assert.deepStrictEqual(lessThan(unsafeFromString("3"), unsafeFromString("3")), false)
477
- * assert.deepStrictEqual(lessThan(unsafeFromString("4"), unsafeFromString("3")), false)
478
- * ```
479
- *
480
- * @since 2.0.0
481
- * @category predicates
482
- */
483
- export const lessThan: {
484
- (that: BigDecimal): (self: BigDecimal) => boolean
485
- (self: BigDecimal, that: BigDecimal): boolean
486
- } = order.lessThan(Order)
487
-
488
- /**
489
- * Checks if a given `BigDecimal` is less than or equal to the provided one.
490
- *
491
- * @example
492
- * ```ts
493
- * import * as assert from "node:assert"
494
- * import { lessThanOrEqualTo, unsafeFromString } from "effect/BigDecimal"
495
- *
496
- * assert.deepStrictEqual(lessThanOrEqualTo(unsafeFromString("2"), unsafeFromString("3")), true)
497
- * assert.deepStrictEqual(lessThanOrEqualTo(unsafeFromString("3"), unsafeFromString("3")), true)
498
- * assert.deepStrictEqual(lessThanOrEqualTo(unsafeFromString("4"), unsafeFromString("3")), false)
499
- * ```
500
- *
501
- * @since 2.0.0
502
- * @category predicates
503
- */
504
- export const lessThanOrEqualTo: {
505
- (that: BigDecimal): (self: BigDecimal) => boolean
506
- (self: BigDecimal, that: BigDecimal): boolean
507
- } = order.lessThanOrEqualTo(Order)
508
-
509
- /**
510
- * Returns `true` if the first argument is greater than the second, otherwise `false`.
511
- *
512
- * @example
513
- * ```ts
514
- * import * as assert from "node:assert"
515
- * import { greaterThan, unsafeFromString } from "effect/BigDecimal"
516
- *
517
- * assert.deepStrictEqual(greaterThan(unsafeFromString("2"), unsafeFromString("3")), false)
518
- * assert.deepStrictEqual(greaterThan(unsafeFromString("3"), unsafeFromString("3")), false)
519
- * assert.deepStrictEqual(greaterThan(unsafeFromString("4"), unsafeFromString("3")), true)
520
- * ```
521
- *
522
- * @since 2.0.0
523
- * @category predicates
524
- */
525
- export const greaterThan: {
526
- (that: BigDecimal): (self: BigDecimal) => boolean
527
- (self: BigDecimal, that: BigDecimal): boolean
528
- } = order.greaterThan(Order)
529
-
530
- /**
531
- * Checks if a given `BigDecimal` is greater than or equal to the provided one.
532
- *
533
- * @example
534
- * ```ts
535
- * import * as assert from "node:assert"
536
- * import { greaterThanOrEqualTo, unsafeFromString } from "effect/BigDecimal"
537
- *
538
- * assert.deepStrictEqual(greaterThanOrEqualTo(unsafeFromString("2"), unsafeFromString("3")), false)
539
- * assert.deepStrictEqual(greaterThanOrEqualTo(unsafeFromString("3"), unsafeFromString("3")), true)
540
- * assert.deepStrictEqual(greaterThanOrEqualTo(unsafeFromString("4"), unsafeFromString("3")), true)
541
- * ```
542
- *
543
- * @since 2.0.0
544
- * @category predicates
545
- */
546
- export const greaterThanOrEqualTo: {
547
- (that: BigDecimal): (self: BigDecimal) => boolean
548
- (self: BigDecimal, that: BigDecimal): boolean
549
- } = order.greaterThanOrEqualTo(Order)
550
-
551
- /**
552
- * Checks if a `BigDecimal` is between a `minimum` and `maximum` value (inclusive).
553
- *
554
- * @example
555
- * ```ts
556
- * import * as assert from "node:assert"
557
- * import { BigDecimal } from "effect"
558
- *
559
- * const between = BigDecimal.between({
560
- * minimum: BigDecimal.unsafeFromString("1"),
561
- * maximum: BigDecimal.unsafeFromString("5") }
562
- * )
563
- *
564
- * assert.deepStrictEqual(between(BigDecimal.unsafeFromString("3")), true)
565
- * assert.deepStrictEqual(between(BigDecimal.unsafeFromString("0")), false)
566
- * assert.deepStrictEqual(between(BigDecimal.unsafeFromString("6")), false)
567
- * ```
568
- *
569
- * @since 2.0.0
570
- * @category predicates
571
- */
572
- export const between: {
573
- (options: {
574
- minimum: BigDecimal
575
- maximum: BigDecimal
576
- }): (self: BigDecimal) => boolean
577
- (self: BigDecimal, options: {
578
- minimum: BigDecimal
579
- maximum: BigDecimal
580
- }): boolean
581
- } = order.between(Order)
582
-
583
- /**
584
- * Restricts the given `BigDecimal` to be within the range specified by the `minimum` and `maximum` values.
585
- *
586
- * - If the `BigDecimal` is less than the `minimum` value, the function returns the `minimum` value.
587
- * - If the `BigDecimal` is greater than the `maximum` value, the function returns the `maximum` value.
588
- * - Otherwise, it returns the original `BigDecimal`.
589
- *
590
- * @example
591
- * ```ts
592
- * import * as assert from "node:assert"
593
- * import { BigDecimal } from "effect"
594
- *
595
- * const clamp = BigDecimal.clamp({
596
- * minimum: BigDecimal.unsafeFromString("1"),
597
- * maximum: BigDecimal.unsafeFromString("5") }
598
- * )
599
- *
600
- * assert.deepStrictEqual(clamp(BigDecimal.unsafeFromString("3")), BigDecimal.unsafeFromString("3"))
601
- * assert.deepStrictEqual(clamp(BigDecimal.unsafeFromString("0")), BigDecimal.unsafeFromString("1"))
602
- * assert.deepStrictEqual(clamp(BigDecimal.unsafeFromString("6")), BigDecimal.unsafeFromString("5"))
603
- * ```
604
- *
605
- * @since 2.0.0
606
- * @category math
607
- */
608
- export const clamp: {
609
- (options: {
610
- minimum: BigDecimal
611
- maximum: BigDecimal
612
- }): (self: BigDecimal) => BigDecimal
613
- (self: BigDecimal, options: {
614
- minimum: BigDecimal
615
- maximum: BigDecimal
616
- }): BigDecimal
617
- } = order.clamp(Order)
618
-
619
- /**
620
- * Returns the minimum between two `BigDecimal`s.
621
- *
622
- * @example
623
- * ```ts
624
- * import * as assert from "node:assert"
625
- * import { min, unsafeFromString } from "effect/BigDecimal"
626
- *
627
- * assert.deepStrictEqual(min(unsafeFromString("2"), unsafeFromString("3")), unsafeFromString("2"))
628
- * ```
629
- *
630
- * @since 2.0.0
631
- * @category math
632
- */
633
- export const min: {
634
- (that: BigDecimal): (self: BigDecimal) => BigDecimal
635
- (self: BigDecimal, that: BigDecimal): BigDecimal
636
- } = order.min(Order)
637
-
638
- /**
639
- * Returns the maximum between two `BigDecimal`s.
640
- *
641
- * @example
642
- * ```ts
643
- * import * as assert from "node:assert"
644
- * import { max, unsafeFromString } from "effect/BigDecimal"
645
- *
646
- * assert.deepStrictEqual(max(unsafeFromString("2"), unsafeFromString("3")), unsafeFromString("3"))
647
- * ```
648
- *
649
- * @since 2.0.0
650
- * @category math
651
- */
652
- export const max: {
653
- (that: BigDecimal): (self: BigDecimal) => BigDecimal
654
- (self: BigDecimal, that: BigDecimal): BigDecimal
655
- } = order.max(Order)
656
-
657
- /**
658
- * Determines the sign of a given `BigDecimal`.
659
- *
660
- * @example
661
- * ```ts
662
- * import * as assert from "node:assert"
663
- * import { sign, unsafeFromString } from "effect/BigDecimal"
664
- *
665
- * assert.deepStrictEqual(sign(unsafeFromString("-5")), -1)
666
- * assert.deepStrictEqual(sign(unsafeFromString("0")), 0)
667
- * assert.deepStrictEqual(sign(unsafeFromString("5")), 1)
668
- * ```
669
- *
670
- * @since 2.0.0
671
- * @category math
672
- */
673
- export const sign = (n: BigDecimal): Ordering => n.value === bigint0 ? 0 : n.value < bigint0 ? -1 : 1
674
-
675
- /**
676
- * Determines the absolute value of a given `BigDecimal`.
677
- *
678
- * @example
679
- * ```ts
680
- * import * as assert from "node:assert"
681
- * import { abs, unsafeFromString } from "effect/BigDecimal"
682
- *
683
- * assert.deepStrictEqual(abs(unsafeFromString("-5")), unsafeFromString("5"))
684
- * assert.deepStrictEqual(abs(unsafeFromString("0")), unsafeFromString("0"))
685
- * assert.deepStrictEqual(abs(unsafeFromString("5")), unsafeFromString("5"))
686
- * ```
687
- *
688
- * @since 2.0.0
689
- * @category math
690
- */
691
- export const abs = (n: BigDecimal): BigDecimal => n.value < bigint0 ? make(-n.value, n.scale) : n
692
-
693
- /**
694
- * Provides a negate operation on `BigDecimal`s.
695
- *
696
- * @example
697
- * ```ts
698
- * import * as assert from "node:assert"
699
- * import { negate, unsafeFromString } from "effect/BigDecimal"
700
- *
701
- * assert.deepStrictEqual(negate(unsafeFromString("3")), unsafeFromString("-3"))
702
- * assert.deepStrictEqual(negate(unsafeFromString("-6")), unsafeFromString("6"))
703
- * ```
704
- *
705
- * @since 2.0.0
706
- * @category math
707
- */
708
- export const negate = (n: BigDecimal): BigDecimal => make(-n.value, n.scale)
709
-
710
- /**
711
- * Returns the remainder left over when one operand is divided by a second operand.
712
- *
713
- * If the divisor is `0`, the result will be `None`.
714
- *
715
- * @example
716
- * ```ts
717
- * import * as assert from "node:assert"
718
- * import { BigDecimal, Option } from "effect"
719
- *
720
- * assert.deepStrictEqual(BigDecimal.remainder(BigDecimal.unsafeFromString("2"), BigDecimal.unsafeFromString("2")), Option.some(BigDecimal.unsafeFromString("0")))
721
- * assert.deepStrictEqual(BigDecimal.remainder(BigDecimal.unsafeFromString("3"), BigDecimal.unsafeFromString("2")), Option.some(BigDecimal.unsafeFromString("1")))
722
- * assert.deepStrictEqual(BigDecimal.remainder(BigDecimal.unsafeFromString("-4"), BigDecimal.unsafeFromString("2")), Option.some(BigDecimal.unsafeFromString("0")))
723
- * ```
724
- *
725
- * @since 2.0.0
726
- * @category math
727
- */
728
- export const remainder: {
729
- (divisor: BigDecimal): (self: BigDecimal) => Option.Option<BigDecimal>
730
- (self: BigDecimal, divisor: BigDecimal): Option.Option<BigDecimal>
731
- } = dual(2, (self: BigDecimal, divisor: BigDecimal): Option.Option<BigDecimal> => {
732
- if (divisor.value === bigint0) {
733
- return Option.none()
734
- }
735
-
736
- const max = Math.max(self.scale, divisor.scale)
737
- return Option.some(make(scale(self, max).value % scale(divisor, max).value, max))
738
- })
739
-
740
- /**
741
- * Returns the remainder left over when one operand is divided by a second operand.
742
- *
743
- * Throws a `RangeError` if the divisor is `0`.
744
- *
745
- * @example
746
- * ```ts
747
- * import * as assert from "node:assert"
748
- * import { unsafeRemainder, unsafeFromString } from "effect/BigDecimal"
749
- *
750
- * assert.deepStrictEqual(unsafeRemainder(unsafeFromString("2"), unsafeFromString("2")), unsafeFromString("0"))
751
- * assert.deepStrictEqual(unsafeRemainder(unsafeFromString("3"), unsafeFromString("2")), unsafeFromString("1"))
752
- * assert.deepStrictEqual(unsafeRemainder(unsafeFromString("-4"), unsafeFromString("2")), unsafeFromString("0"))
753
- * ```
754
- *
755
- * @since 2.0.0
756
- * @category math
757
- */
758
- export const unsafeRemainder: {
759
- (divisor: BigDecimal): (self: BigDecimal) => BigDecimal
760
- (self: BigDecimal, divisor: BigDecimal): BigDecimal
761
- } = dual(2, (self: BigDecimal, divisor: BigDecimal): BigDecimal => {
762
- if (divisor.value === bigint0) {
763
- throw new RangeError("Division by zero")
764
- }
765
-
766
- const max = Math.max(self.scale, divisor.scale)
767
- return make(scale(self, max).value % scale(divisor, max).value, max)
768
- })
769
-
770
- /**
771
- * @category instances
772
- * @since 2.0.0
773
- */
774
- export const Equivalence: equivalence.Equivalence<BigDecimal> = equivalence.make((self, that) => {
775
- if (self.scale > that.scale) {
776
- return scale(that, self.scale).value === self.value
777
- }
778
-
779
- if (self.scale < that.scale) {
780
- return scale(self, that.scale).value === that.value
781
- }
782
-
783
- return self.value === that.value
784
- })
785
-
786
- /**
787
- * Checks if two `BigDecimal`s are equal.
788
- *
789
- * @since 2.0.0
790
- * @category predicates
791
- */
792
- export const equals: {
793
- (that: BigDecimal): (self: BigDecimal) => boolean
794
- (self: BigDecimal, that: BigDecimal): boolean
795
- } = dual(2, (self: BigDecimal, that: BigDecimal): boolean => Equivalence(self, that))
796
-
797
- /**
798
- * Creates a `BigDecimal` from a `bigint` value.
799
- *
800
- * @since 2.0.0
801
- * @category constructors
802
- */
803
- export const fromBigInt = (n: bigint): BigDecimal => make(n, 0)
804
-
805
- /**
806
- * Creates a `BigDecimal` from a `number` value.
807
- *
808
- * It is not recommended to convert a floating point number to a decimal directly,
809
- * as the floating point representation may be unexpected.
810
- *
811
- * Throws a `RangeError` if the number is not finite (`NaN`, `+Infinity` or `-Infinity`).
812
- *
813
- * @example
814
- * ```ts
815
- * import * as assert from "node:assert"
816
- * import { unsafeFromNumber, make } from "effect/BigDecimal"
817
- *
818
- * assert.deepStrictEqual(unsafeFromNumber(123), make(123n, 0))
819
- * assert.deepStrictEqual(unsafeFromNumber(123.456), make(123456n, 3))
820
- * ```
821
- *
822
- * @since 3.11.0
823
- * @category constructors
824
- */
825
- export const unsafeFromNumber = (n: number): BigDecimal =>
826
- Option.getOrThrowWith(safeFromNumber(n), () => new RangeError(`Number must be finite, got ${n}`))
827
-
828
- /**
829
- * Creates a `BigDecimal` from a `number` value.
830
- *
831
- * It is not recommended to convert a floating point number to a decimal directly,
832
- * as the floating point representation may be unexpected.
833
- *
834
- * Throws a `RangeError` if the number is not finite (`NaN`, `+Infinity` or `-Infinity`).
835
- *
836
- * @since 2.0.0
837
- * @category constructors
838
- * @deprecated Use {@link unsafeFromNumber} instead.
839
- */
840
- export const fromNumber: (n: number) => BigDecimal = unsafeFromNumber
841
-
842
- // TODO(4.0): Rename this to `fromNumber` after removing the current, unsafe implementation of `fromNumber`.
843
- /**
844
- * Creates a `BigDecimal` from a `number` value.
845
- *
846
- * It is not recommended to convert a floating point number to a decimal directly,
847
- * as the floating point representation may be unexpected.
848
- *
849
- * Returns `None` if the number is not finite (`NaN`, `+Infinity` or `-Infinity`).
850
- *
851
- * @example
852
- * ```ts
853
- * import * as assert from "node:assert"
854
- * import { BigDecimal, Option } from "effect"
855
- *
856
- * assert.deepStrictEqual(BigDecimal.safeFromNumber(123), Option.some(BigDecimal.make(123n, 0)))
857
- * assert.deepStrictEqual(BigDecimal.safeFromNumber(123.456), Option.some(BigDecimal.make(123456n, 3)))
858
- * assert.deepStrictEqual(BigDecimal.safeFromNumber(Infinity), Option.none())
859
- * ```
860
- *
861
- * @since 3.11.0
862
- * @category constructors
863
- */
864
- export const safeFromNumber = (n: number): Option.Option<BigDecimal> => {
865
- if (!Number.isFinite(n)) {
866
- return Option.none()
867
- }
868
-
869
- const string = `${n}`
870
- if (string.includes("e")) {
871
- return fromString(string)
872
- }
873
-
874
- const [lead, trail = ""] = string.split(".")
875
- return Option.some(make(BigInt(`${lead}${trail}`), trail.length))
876
- }
877
-
878
- /**
879
- * Parses a numerical `string` into a `BigDecimal`.
880
- *
881
- * @example
882
- * ```ts
883
- * import * as assert from "node:assert"
884
- * import { BigDecimal, Option } from "effect"
885
- *
886
- * assert.deepStrictEqual(BigDecimal.fromString("123"), Option.some(BigDecimal.make(123n, 0)))
887
- * assert.deepStrictEqual(BigDecimal.fromString("123.456"), Option.some(BigDecimal.make(123456n, 3)))
888
- * assert.deepStrictEqual(BigDecimal.fromString("123.abc"), Option.none())
889
- * ```
890
- *
891
- * @since 2.0.0
892
- * @category constructors
893
- */
894
- export const fromString = (s: string): Option.Option<BigDecimal> => {
895
- if (s === "") {
896
- return Option.some(zero)
897
- }
898
-
899
- let base: string
900
- let exp: number
901
- const seperator = s.search(/[eE]/)
902
- if (seperator !== -1) {
903
- const trail = s.slice(seperator + 1)
904
- base = s.slice(0, seperator)
905
- exp = Number(trail)
906
- if (base === "" || !Number.isSafeInteger(exp) || !FINITE_INT_REGEX.test(trail)) {
907
- return Option.none()
908
- }
909
- } else {
910
- base = s
911
- exp = 0
912
- }
913
-
914
- let digits: string
915
- let offset: number
916
- const dot = base.search(/\./)
917
- if (dot !== -1) {
918
- const lead = base.slice(0, dot)
919
- const trail = base.slice(dot + 1)
920
- digits = `${lead}${trail}`
921
- offset = trail.length
922
- } else {
923
- digits = base
924
- offset = 0
925
- }
926
-
927
- if (!FINITE_INT_REGEX.test(digits)) {
928
- return Option.none()
929
- }
930
-
931
- const scale = offset - exp
932
- if (!Number.isSafeInteger(scale)) {
933
- return Option.none()
934
- }
935
-
936
- return Option.some(make(BigInt(digits), scale))
937
- }
938
-
939
- /**
940
- * Parses a numerical `string` into a `BigDecimal`.
941
- *
942
- * @example
943
- * ```ts
944
- * import * as assert from "node:assert"
945
- * import { unsafeFromString, make } from "effect/BigDecimal"
946
- *
947
- * assert.deepStrictEqual(unsafeFromString("123"), make(123n, 0))
948
- * assert.deepStrictEqual(unsafeFromString("123.456"), make(123456n, 3))
949
- * assert.throws(() => unsafeFromString("123.abc"))
950
- * ```
951
- *
952
- * @since 2.0.0
953
- * @category constructors
954
- */
955
- export const unsafeFromString = (s: string): BigDecimal =>
956
- Option.getOrThrowWith(fromString(s), () => new Error("Invalid numerical string"))
957
-
958
- /**
959
- * Formats a given `BigDecimal` as a `string`.
960
- *
961
- * If the scale of the `BigDecimal` is greater than or equal to 16, the `BigDecimal` will
962
- * be formatted in scientific notation.
963
- *
964
- * @example
965
- * ```ts
966
- * import * as assert from "node:assert"
967
- * import { format, unsafeFromString } from "effect/BigDecimal"
968
- *
969
- * assert.deepStrictEqual(format(unsafeFromString("-5")), "-5")
970
- * assert.deepStrictEqual(format(unsafeFromString("123.456")), "123.456")
971
- * assert.deepStrictEqual(format(unsafeFromString("-0.00000123")), "-0.00000123")
972
- * ```
973
- *
974
- * @since 2.0.0
975
- * @category conversions
976
- */
977
- export const format = (n: BigDecimal): string => {
978
- const normalized = normalize(n)
979
- if (Math.abs(normalized.scale) >= 16) {
980
- return toExponential(normalized)
981
- }
982
-
983
- const negative = normalized.value < bigint0
984
- const absolute = negative ? `${normalized.value}`.substring(1) : `${normalized.value}`
985
-
986
- let before: string
987
- let after: string
988
-
989
- if (normalized.scale >= absolute.length) {
990
- before = "0"
991
- after = "0".repeat(normalized.scale - absolute.length) + absolute
992
- } else {
993
- const location = absolute.length - normalized.scale
994
- if (location > absolute.length) {
995
- const zeros = location - absolute.length
996
- before = `${absolute}${"0".repeat(zeros)}`
997
- after = ""
998
- } else {
999
- after = absolute.slice(location)
1000
- before = absolute.slice(0, location)
1001
- }
1002
- }
1003
-
1004
- const complete = after === "" ? before : `${before}.${after}`
1005
- return negative ? `-${complete}` : complete
1006
- }
1007
-
1008
- /**
1009
- * Formats a given `BigDecimal` as a `string` in scientific notation.
1010
- *
1011
- * @example
1012
- * ```ts
1013
- * import * as assert from "node:assert"
1014
- * import { toExponential, make } from "effect/BigDecimal"
1015
- *
1016
- * assert.deepStrictEqual(toExponential(make(123456n, -5)), "1.23456e+10")
1017
- * ```
1018
- *
1019
- * @since 3.11.0
1020
- * @category conversions
1021
- */
1022
- export const toExponential = (n: BigDecimal): string => {
1023
- if (isZero(n)) {
1024
- return "0e+0"
1025
- }
1026
-
1027
- const normalized = normalize(n)
1028
- const digits = `${abs(normalized).value}`
1029
- const head = digits.slice(0, 1)
1030
- const tail = digits.slice(1)
1031
-
1032
- let output = `${isNegative(normalized) ? "-" : ""}${head}`
1033
- if (tail !== "") {
1034
- output += `.${tail}`
1035
- }
1036
-
1037
- const exp = tail.length - normalized.scale
1038
- return `${output}e${exp >= 0 ? "+" : ""}${exp}`
1039
- }
1040
-
1041
- /**
1042
- * Converts a `BigDecimal` to a `number`.
1043
- *
1044
- * This function will produce incorrect results if the `BigDecimal` exceeds the 64-bit range of a `number`.
1045
- *
1046
- * @example
1047
- * ```ts
1048
- * import * as assert from "node:assert"
1049
- * import { unsafeToNumber, unsafeFromString } from "effect/BigDecimal"
1050
- *
1051
- * assert.deepStrictEqual(unsafeToNumber(unsafeFromString("123.456")), 123.456)
1052
- * ```
1053
- *
1054
- * @since 2.0.0
1055
- * @category conversions
1056
- */
1057
- export const unsafeToNumber = (n: BigDecimal): number => Number(format(n))
1058
-
1059
- /**
1060
- * Checks if a given `BigDecimal` is an integer.
1061
- *
1062
- * @example
1063
- * ```ts
1064
- * import * as assert from "node:assert"
1065
- * import { isInteger, unsafeFromString } from "effect/BigDecimal"
1066
- *
1067
- * assert.deepStrictEqual(isInteger(unsafeFromString("0")), true)
1068
- * assert.deepStrictEqual(isInteger(unsafeFromString("1")), true)
1069
- * assert.deepStrictEqual(isInteger(unsafeFromString("1.1")), false)
1070
- * ```
1071
- *
1072
- * @since 2.0.0
1073
- * @category predicates
1074
- */
1075
- export const isInteger = (n: BigDecimal): boolean => normalize(n).scale <= 0
1076
-
1077
- /**
1078
- * Checks if a given `BigDecimal` is `0`.
1079
- *
1080
- * @example
1081
- * ```ts
1082
- * import * as assert from "node:assert"
1083
- * import { isZero, unsafeFromString } from "effect/BigDecimal"
1084
- *
1085
- * assert.deepStrictEqual(isZero(unsafeFromString("0")), true)
1086
- * assert.deepStrictEqual(isZero(unsafeFromString("1")), false)
1087
- * ```
1088
- *
1089
- * @since 2.0.0
1090
- * @category predicates
1091
- */
1092
- export const isZero = (n: BigDecimal): boolean => n.value === bigint0
1093
-
1094
- /**
1095
- * Checks if a given `BigDecimal` is negative.
1096
- *
1097
- * @example
1098
- * ```ts
1099
- * import * as assert from "node:assert"
1100
- * import { isNegative, unsafeFromString } from "effect/BigDecimal"
1101
- *
1102
- * assert.deepStrictEqual(isNegative(unsafeFromString("-1")), true)
1103
- * assert.deepStrictEqual(isNegative(unsafeFromString("0")), false)
1104
- * assert.deepStrictEqual(isNegative(unsafeFromString("1")), false)
1105
- * ```
1106
- *
1107
- * @since 2.0.0
1108
- * @category predicates
1109
- */
1110
- export const isNegative = (n: BigDecimal): boolean => n.value < bigint0
1111
-
1112
- /**
1113
- * Checks if a given `BigDecimal` is positive.
1114
- *
1115
- * @example
1116
- * ```ts
1117
- * import * as assert from "node:assert"
1118
- * import { isPositive, unsafeFromString } from "effect/BigDecimal"
1119
- *
1120
- * assert.deepStrictEqual(isPositive(unsafeFromString("-1")), false)
1121
- * assert.deepStrictEqual(isPositive(unsafeFromString("0")), false)
1122
- * assert.deepStrictEqual(isPositive(unsafeFromString("1")), true)
1123
- * ```
1124
- *
1125
- * @since 2.0.0
1126
- * @category predicates
1127
- */
1128
- export const isPositive = (n: BigDecimal): boolean => n.value > bigint0
1129
-
1130
- const isBigDecimalArgs = (args: IArguments) => isBigDecimal(args[0])
1131
-
1132
- /**
1133
- * Calculate the ceiling of a `BigDecimal` at the given scale.
1134
- *
1135
- * @example
1136
- * ```ts
1137
- * import * as assert from "node:assert"
1138
- * import { ceil, unsafeFromString } from "effect/BigDecimal"
1139
- *
1140
- * assert.deepStrictEqual(ceil(unsafeFromString("145"), -1), unsafeFromString("150"))
1141
- * assert.deepStrictEqual(ceil(unsafeFromString("-14.5")), unsafeFromString("-14"))
1142
- * ```
1143
- *
1144
- * @since 3.16.0
1145
- * @category math
1146
- */
1147
- export const ceil: {
1148
- (scale: number): (self: BigDecimal) => BigDecimal
1149
- (self: BigDecimal, scale?: number): BigDecimal
1150
- } = dual(isBigDecimalArgs, (self: BigDecimal, scale: number = 0): BigDecimal => {
1151
- const truncated = truncate(self, scale)
1152
-
1153
- if (isPositive(self) && lessThan(truncated, self)) {
1154
- return sum(truncated, make(1n, scale))
1155
- }
1156
-
1157
- return truncated
1158
- })
1159
-
1160
- /**
1161
- * Calculate the floor of a `BigDecimal` at the given scale.
1162
- *
1163
- * @example
1164
- * ```ts
1165
- * import * as assert from "node:assert"
1166
- * import { floor, unsafeFromString } from "effect/BigDecimal"
1167
- *
1168
- * assert.deepStrictEqual(floor(unsafeFromString("145"), -1), unsafeFromString("140"))
1169
- * assert.deepStrictEqual(floor(unsafeFromString("-14.5")), unsafeFromString("-15"))
1170
- * ```
1171
- *
1172
- * @since 3.16.0
1173
- * @category math
1174
- */
1175
- export const floor: {
1176
- (scale: number): (self: BigDecimal) => BigDecimal
1177
- (self: BigDecimal, scale?: number): BigDecimal
1178
- } = dual(isBigDecimalArgs, (self: BigDecimal, scale: number = 0): BigDecimal => {
1179
- const truncated = truncate(self, scale)
1180
-
1181
- if (isNegative(self) && greaterThan(truncated, self)) {
1182
- return sum(truncated, make(-1n, scale))
1183
- }
1184
-
1185
- return truncated
1186
- })
1187
-
1188
- /**
1189
- * Truncate a `BigDecimal` at the given scale. This is the same operation as rounding away from zero.
1190
- *
1191
- * @example
1192
- * ```ts
1193
- * import * as assert from "node:assert"
1194
- * import { truncate, unsafeFromString } from "effect/BigDecimal"
1195
- *
1196
- * assert.deepStrictEqual(truncate(unsafeFromString("145"), -1), unsafeFromString("140"))
1197
- * assert.deepStrictEqual(truncate(unsafeFromString("-14.5")), unsafeFromString("-14"))
1198
- * ```
1199
- *
1200
- * @since 3.16.0
1201
- * @category math
1202
- */
1203
- export const truncate: {
1204
- (scale: number): (self: BigDecimal) => BigDecimal
1205
- (self: BigDecimal, scale?: number): BigDecimal
1206
- } = dual(isBigDecimalArgs, (self: BigDecimal, scale: number = 0): BigDecimal => {
1207
- if (self.scale <= scale) {
1208
- return self
1209
- }
1210
-
1211
- // BigInt division truncates towards zero
1212
- return make(self.value / (10n ** BigInt(self.scale - scale)), scale)
1213
- })
1214
-
1215
- /**
1216
- * Internal function used by `round` for `half-even` and `half-odd` rounding modes.
1217
- *
1218
- * Returns the digit at the position of the given `scale` within the `BigDecimal`.
1219
- *
1220
- * @internal
1221
- */
1222
- export const digitAt: {
1223
- (scale: number): (self: BigDecimal) => bigint
1224
- (self: BigDecimal, scale: number): bigint
1225
- } = dual(2, (self: BigDecimal, scale: number): bigint => {
1226
- if (self.scale < scale) {
1227
- return 0n
1228
- }
1229
-
1230
- const scaled = self.value / (10n ** BigInt(self.scale - scale))
1231
- return scaled % 10n
1232
- })
1233
-
1234
- /**
1235
- * Rounding modes for `BigDecimal`.
1236
- *
1237
- * `ceil`: round towards positive infinity
1238
- * `floor`: round towards negative infinity
1239
- * `to-zero`: round towards zero
1240
- * `from-zero`: round away from zero
1241
- * `half-ceil`: round to the nearest neighbor; if equidistant round towards positive infinity
1242
- * `half-floor`: round to the nearest neighbor; if equidistant round towards negative infinity
1243
- * `half-to-zero`: round to the nearest neighbor; if equidistant round towards zero
1244
- * `half-from-zero`: round to the nearest neighbor; if equidistant round away from zero
1245
- * `half-even`: round to the nearest neighbor; if equidistant round to the neighbor with an even digit
1246
- * `half-odd`: round to the nearest neighbor; if equidistant round to the neighbor with an odd digit
1247
- *
1248
- * @since 3.16.0
1249
- * @category math
1250
- */
1251
- export type RoundingMode =
1252
- | "ceil"
1253
- | "floor"
1254
- | "to-zero"
1255
- | "from-zero"
1256
- | "half-ceil"
1257
- | "half-floor"
1258
- | "half-to-zero"
1259
- | "half-from-zero"
1260
- | "half-even"
1261
- | "half-odd"
1262
-
1263
- /**
1264
- * Rounds a `BigDecimal` at the given scale with the specified rounding mode.
1265
- *
1266
- * @example
1267
- * ```ts
1268
- * import * as assert from "node:assert"
1269
- * import { round, unsafeFromString } from "effect/BigDecimal"
1270
- *
1271
- * assert.deepStrictEqual(round(unsafeFromString("145"), { mode: "from-zero", scale: -1 }), unsafeFromString("150"))
1272
- * assert.deepStrictEqual(round(unsafeFromString("-14.5")), unsafeFromString("-15"))
1273
- * ```
1274
- *
1275
- * @since 3.16.0
1276
- * @category math
1277
- */
1278
- export const round: {
1279
- (options: { scale?: number; mode?: RoundingMode }): (self: BigDecimal) => BigDecimal
1280
- (n: BigDecimal, options?: { scale?: number; mode?: RoundingMode }): BigDecimal
1281
- } = dual(isBigDecimalArgs, (self: BigDecimal, options?: { scale?: number; mode?: RoundingMode }): BigDecimal => {
1282
- const mode = options?.mode ?? "half-from-zero"
1283
- const scale = options?.scale ?? 0
1284
-
1285
- switch (mode) {
1286
- case "ceil":
1287
- return ceil(self, scale)
1288
-
1289
- case "floor":
1290
- return floor(self, scale)
1291
-
1292
- case "to-zero":
1293
- return truncate(self, scale)
1294
-
1295
- case "from-zero":
1296
- return (isPositive(self) ? ceil(self, scale) : floor(self, scale))
1297
-
1298
- case "half-ceil":
1299
- return floor(sum(self, make(5n, scale + 1)), scale)
1300
-
1301
- case "half-floor":
1302
- return ceil(sum(self, make(-5n, scale + 1)), scale)
1303
-
1304
- case "half-to-zero":
1305
- return isNegative(self)
1306
- ? floor(sum(self, make(5n, scale + 1)), scale)
1307
- : ceil(sum(self, make(-5n, scale + 1)), scale)
1308
-
1309
- case "half-from-zero":
1310
- return isNegative(self)
1311
- ? ceil(sum(self, make(-5n, scale + 1)), scale)
1312
- : floor(sum(self, make(5n, scale + 1)), scale)
1313
- }
1314
-
1315
- const halfCeil = floor(sum(self, make(5n, scale + 1)), scale)
1316
- const halfFloor = ceil(sum(self, make(-5n, scale + 1)), scale)
1317
- const digit = digitAt(halfCeil, scale)
1318
-
1319
- switch (mode) {
1320
- case "half-even":
1321
- return equals(halfCeil, halfFloor) ? halfCeil : (digit % 2n === 0n) ? halfCeil : halfFloor
1322
-
1323
- case "half-odd":
1324
- return equals(halfCeil, halfFloor) ? halfCeil : (digit % 2n === 0n) ? halfFloor : halfCeil
1325
- }
1326
- })
1327
-
1328
- /**
1329
- * Takes an `Iterable` of `BigDecimal`s and returns their sum as a single `BigDecimal`
1330
- *
1331
- * @example
1332
- * ```ts
1333
- * import * as assert from "node:assert"
1334
- * import { unsafeFromString, sumAll } from "effect/BigDecimal"
1335
- *
1336
- * assert.deepStrictEqual(sumAll([unsafeFromString("2"), unsafeFromString("3"), unsafeFromString("4")]), unsafeFromString("9"))
1337
- * ```
1338
- *
1339
- * @category math
1340
- * @since 3.16.0
1341
- */
1342
- export const sumAll = (collection: Iterable<BigDecimal>): BigDecimal => {
1343
- let out = zero
1344
- for (const n of collection) {
1345
- out = sum(out, n)
1346
- }
1347
-
1348
- return out
1349
- }