effect 3.12.11 → 3.13.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 (204) hide show
  1. package/README.md +38 -49
  2. package/dist/cjs/Channel.js.map +1 -1
  3. package/dist/cjs/DateTime.js +17 -1
  4. package/dist/cjs/DateTime.js.map +1 -1
  5. package/dist/cjs/Differ.js.map +1 -1
  6. package/dist/cjs/Duration.js +128 -1
  7. package/dist/cjs/Duration.js.map +1 -1
  8. package/dist/cjs/Effect.js +175 -37
  9. package/dist/cjs/Effect.js.map +1 -1
  10. package/dist/cjs/Either.js +2 -1
  11. package/dist/cjs/Either.js.map +1 -1
  12. package/dist/cjs/FiberHandle.js +54 -21
  13. package/dist/cjs/FiberHandle.js.map +1 -1
  14. package/dist/cjs/FiberMap.js +51 -24
  15. package/dist/cjs/FiberMap.js.map +1 -1
  16. package/dist/cjs/FiberSet.js +50 -17
  17. package/dist/cjs/FiberSet.js.map +1 -1
  18. package/dist/cjs/HashMap.js +19 -1
  19. package/dist/cjs/HashMap.js.map +1 -1
  20. package/dist/cjs/HashSet.js +9 -1
  21. package/dist/cjs/HashSet.js.map +1 -1
  22. package/dist/cjs/Layer.js +21 -1
  23. package/dist/cjs/Layer.js.map +1 -1
  24. package/dist/cjs/Match.js +659 -38
  25. package/dist/cjs/Match.js.map +1 -1
  26. package/dist/cjs/RcMap.js +11 -1
  27. package/dist/cjs/RcMap.js.map +1 -1
  28. package/dist/cjs/Reloadable.js.map +1 -1
  29. package/dist/cjs/STM.js.map +1 -1
  30. package/dist/cjs/Schedule.js +1074 -309
  31. package/dist/cjs/Schedule.js.map +1 -1
  32. package/dist/cjs/Schema.js +73 -1
  33. package/dist/cjs/Schema.js.map +1 -1
  34. package/dist/cjs/Stream.js.map +1 -1
  35. package/dist/cjs/internal/channel.js.map +1 -1
  36. package/dist/cjs/internal/core-effect.js.map +1 -1
  37. package/dist/cjs/internal/core.js +27 -3
  38. package/dist/cjs/internal/core.js.map +1 -1
  39. package/dist/cjs/internal/dateTime.js +4 -1
  40. package/dist/cjs/internal/dateTime.js.map +1 -1
  41. package/dist/cjs/internal/differ.js +4 -0
  42. package/dist/cjs/internal/differ.js.map +1 -1
  43. package/dist/cjs/internal/effect/circular.js +3 -2
  44. package/dist/cjs/internal/effect/circular.js.map +1 -1
  45. package/dist/cjs/internal/fiberRuntime.js +21 -7
  46. package/dist/cjs/internal/fiberRuntime.js.map +1 -1
  47. package/dist/cjs/internal/hashMap.js +10 -1
  48. package/dist/cjs/internal/hashMap.js.map +1 -1
  49. package/dist/cjs/internal/keyedPool.js +1 -1
  50. package/dist/cjs/internal/keyedPool.js.map +1 -1
  51. package/dist/cjs/internal/layer.js.map +1 -1
  52. package/dist/cjs/internal/rcMap.js +86 -56
  53. package/dist/cjs/internal/rcMap.js.map +1 -1
  54. package/dist/cjs/internal/reloadable.js.map +1 -1
  55. package/dist/cjs/internal/schedule.js.map +1 -1
  56. package/dist/cjs/internal/sink.js.map +1 -1
  57. package/dist/cjs/internal/stm/stm.js.map +1 -1
  58. package/dist/cjs/internal/stream.js.map +1 -1
  59. package/dist/cjs/internal/version.js +1 -1
  60. package/dist/cjs/internal/version.js.map +1 -1
  61. package/dist/dts/Channel.d.ts +4 -4
  62. package/dist/dts/Channel.d.ts.map +1 -1
  63. package/dist/dts/DateTime.d.ts +16 -0
  64. package/dist/dts/DateTime.d.ts.map +1 -1
  65. package/dist/dts/Differ.d.ts +2 -1
  66. package/dist/dts/Differ.d.ts.map +1 -1
  67. package/dist/dts/Duration.d.ts +64 -0
  68. package/dist/dts/Duration.d.ts.map +1 -1
  69. package/dist/dts/Effect.d.ts +402 -30
  70. package/dist/dts/Effect.d.ts.map +1 -1
  71. package/dist/dts/Either.d.ts +7 -0
  72. package/dist/dts/Either.d.ts.map +1 -1
  73. package/dist/dts/FiberHandle.d.ts +26 -0
  74. package/dist/dts/FiberHandle.d.ts.map +1 -1
  75. package/dist/dts/FiberMap.d.ts +26 -0
  76. package/dist/dts/FiberMap.d.ts.map +1 -1
  77. package/dist/dts/FiberSet.d.ts +25 -0
  78. package/dist/dts/FiberSet.d.ts.map +1 -1
  79. package/dist/dts/HashMap.d.ts +38 -0
  80. package/dist/dts/HashMap.d.ts.map +1 -1
  81. package/dist/dts/HashSet.d.ts +7 -0
  82. package/dist/dts/HashSet.d.ts.map +1 -1
  83. package/dist/dts/Layer.d.ts +32 -13
  84. package/dist/dts/Layer.d.ts.map +1 -1
  85. package/dist/dts/Match.d.ts +731 -48
  86. package/dist/dts/Match.d.ts.map +1 -1
  87. package/dist/dts/RcMap.d.ts +32 -0
  88. package/dist/dts/RcMap.d.ts.map +1 -1
  89. package/dist/dts/Reloadable.d.ts +13 -13
  90. package/dist/dts/Reloadable.d.ts.map +1 -1
  91. package/dist/dts/STM.d.ts +4 -4
  92. package/dist/dts/STM.d.ts.map +1 -1
  93. package/dist/dts/Schedule.d.ts +2294 -633
  94. package/dist/dts/Schedule.d.ts.map +1 -1
  95. package/dist/dts/Schema.d.ts +40 -4
  96. package/dist/dts/Schema.d.ts.map +1 -1
  97. package/dist/dts/Stream.d.ts +8 -8
  98. package/dist/dts/Stream.d.ts.map +1 -1
  99. package/dist/dts/Trie.d.ts +7 -7
  100. package/dist/dts/Trie.d.ts.map +1 -1
  101. package/dist/dts/index.d.ts +25 -0
  102. package/dist/dts/index.d.ts.map +1 -1
  103. package/dist/dts/internal/stm/stm.d.ts +2 -2
  104. package/dist/dts/internal/stm/stm.d.ts.map +1 -1
  105. package/dist/esm/Channel.js.map +1 -1
  106. package/dist/esm/DateTime.js +16 -0
  107. package/dist/esm/DateTime.js.map +1 -1
  108. package/dist/esm/Differ.js.map +1 -1
  109. package/dist/esm/Duration.js +124 -0
  110. package/dist/esm/Duration.js.map +1 -1
  111. package/dist/esm/Effect.js +170 -32
  112. package/dist/esm/Effect.js.map +1 -1
  113. package/dist/esm/Either.js +7 -0
  114. package/dist/esm/Either.js.map +1 -1
  115. package/dist/esm/FiberHandle.js +48 -18
  116. package/dist/esm/FiberHandle.js.map +1 -1
  117. package/dist/esm/FiberMap.js +46 -22
  118. package/dist/esm/FiberMap.js.map +1 -1
  119. package/dist/esm/FiberSet.js +45 -15
  120. package/dist/esm/FiberSet.js.map +1 -1
  121. package/dist/esm/HashMap.js +17 -0
  122. package/dist/esm/HashMap.js.map +1 -1
  123. package/dist/esm/HashSet.js +7 -0
  124. package/dist/esm/HashSet.js.map +1 -1
  125. package/dist/esm/Layer.js +20 -0
  126. package/dist/esm/Layer.js.map +1 -1
  127. package/dist/esm/Match.js +665 -40
  128. package/dist/esm/Match.js.map +1 -1
  129. package/dist/esm/RcMap.js +10 -0
  130. package/dist/esm/RcMap.js.map +1 -1
  131. package/dist/esm/Reloadable.js.map +1 -1
  132. package/dist/esm/STM.js.map +1 -1
  133. package/dist/esm/Schedule.js +1074 -309
  134. package/dist/esm/Schedule.js.map +1 -1
  135. package/dist/esm/Schema.js +71 -0
  136. package/dist/esm/Schema.js.map +1 -1
  137. package/dist/esm/Stream.js.map +1 -1
  138. package/dist/esm/index.js +25 -0
  139. package/dist/esm/index.js.map +1 -1
  140. package/dist/esm/internal/channel.js.map +1 -1
  141. package/dist/esm/internal/core-effect.js.map +1 -1
  142. package/dist/esm/internal/core.js +23 -0
  143. package/dist/esm/internal/core.js.map +1 -1
  144. package/dist/esm/internal/dateTime.js +2 -0
  145. package/dist/esm/internal/dateTime.js.map +1 -1
  146. package/dist/esm/internal/differ.js +4 -0
  147. package/dist/esm/internal/differ.js.map +1 -1
  148. package/dist/esm/internal/effect/circular.js +3 -2
  149. package/dist/esm/internal/effect/circular.js.map +1 -1
  150. package/dist/esm/internal/fiberRuntime.js +18 -5
  151. package/dist/esm/internal/fiberRuntime.js.map +1 -1
  152. package/dist/esm/internal/hashMap.js +9 -0
  153. package/dist/esm/internal/hashMap.js.map +1 -1
  154. package/dist/esm/internal/keyedPool.js +1 -1
  155. package/dist/esm/internal/keyedPool.js.map +1 -1
  156. package/dist/esm/internal/layer.js.map +1 -1
  157. package/dist/esm/internal/rcMap.js +85 -55
  158. package/dist/esm/internal/rcMap.js.map +1 -1
  159. package/dist/esm/internal/reloadable.js.map +1 -1
  160. package/dist/esm/internal/schedule.js.map +1 -1
  161. package/dist/esm/internal/sink.js.map +1 -1
  162. package/dist/esm/internal/stm/stm.js.map +1 -1
  163. package/dist/esm/internal/stream.js.map +1 -1
  164. package/dist/esm/internal/version.js +1 -1
  165. package/dist/esm/internal/version.js.map +1 -1
  166. package/package.json +2 -1
  167. package/src/Channel.ts +14 -17
  168. package/src/DateTime.ts +17 -8
  169. package/src/Differ.ts +2 -1
  170. package/src/Duration.ts +147 -0
  171. package/src/Effect.ts +528 -140
  172. package/src/Either.ts +9 -0
  173. package/src/FiberHandle.ts +95 -35
  174. package/src/FiberMap.ts +104 -39
  175. package/src/FiberSet.ts +93 -24
  176. package/src/HashMap.ts +40 -0
  177. package/src/HashSet.ts +8 -0
  178. package/src/Layer.ts +94 -40
  179. package/src/Match.ts +733 -49
  180. package/src/RcMap.ts +34 -0
  181. package/src/Reloadable.ts +17 -27
  182. package/src/STM.ts +10 -17
  183. package/src/Schedule.ts +2325 -653
  184. package/src/Schema.ts +81 -4
  185. package/src/Stream.ts +26 -33
  186. package/src/Trie.ts +7 -7
  187. package/src/index.ts +25 -0
  188. package/src/internal/channel.ts +37 -39
  189. package/src/internal/core-effect.ts +84 -84
  190. package/src/internal/core.ts +80 -0
  191. package/src/internal/dateTime.ts +3 -0
  192. package/src/internal/differ.ts +4 -0
  193. package/src/internal/effect/circular.ts +3 -2
  194. package/src/internal/fiberRuntime.ts +31 -6
  195. package/src/internal/hashMap.ts +16 -0
  196. package/src/internal/keyedPool.ts +1 -1
  197. package/src/internal/layer.ts +52 -52
  198. package/src/internal/rcMap.ts +131 -89
  199. package/src/internal/reloadable.ts +25 -28
  200. package/src/internal/schedule.ts +29 -23
  201. package/src/internal/sink.ts +16 -15
  202. package/src/internal/stm/stm.ts +54 -46
  203. package/src/internal/stream.ts +100 -100
  204. package/src/internal/version.ts +1 -1
@@ -1,4 +1,4 @@
1
- let moduleVersion = "3.12.11";
1
+ let moduleVersion = "3.13.0";
2
2
  export const getCurrentVersion = () => moduleVersion;
3
3
  export const setCurrentVersion = version => {
4
4
  moduleVersion = version;
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","names":["moduleVersion","getCurrentVersion","setCurrentVersion","version"],"sources":["../../../src/internal/version.ts"],"sourcesContent":[null],"mappings":"AAAA,IAAIA,aAAa,GAAG,SAAS;AAE7B,OAAO,MAAMC,iBAAiB,GAAGA,CAAA,KAAMD,aAAa;AAEpD,OAAO,MAAME,iBAAiB,GAAIC,OAAe,IAAI;EACnDH,aAAa,GAAGG,OAAO;AACzB,CAAC","ignoreList":[]}
1
+ {"version":3,"file":"version.js","names":["moduleVersion","getCurrentVersion","setCurrentVersion","version"],"sources":["../../../src/internal/version.ts"],"sourcesContent":[null],"mappings":"AAAA,IAAIA,aAAa,GAAG,QAAQ;AAE5B,OAAO,MAAMC,iBAAiB,GAAGA,CAAA,KAAMD,aAAa;AAEpD,OAAO,MAAME,iBAAiB,GAAIC,OAAe,IAAI;EACnDH,aAAa,GAAGG,OAAO;AACzB,CAAC","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "effect",
3
- "version": "3.12.11",
3
+ "version": "3.13.0",
4
4
  "description": "The missing standard library for TypeScript, for writing production-grade software.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -10,6 +10,7 @@
10
10
  },
11
11
  "sideEffects": [],
12
12
  "dependencies": {
13
+ "@standard-schema/spec": "^1.0.0",
13
14
  "fast-check": "^3.23.1"
14
15
  },
15
16
  "publishConfig": {
package/src/Channel.ts CHANGED
@@ -2456,12 +2456,9 @@ export const provideService: {
2456
2456
  * @since 2.0.0
2457
2457
  * @category context
2458
2458
  */
2459
- <T extends Context.Tag<any, any>>(
2460
- tag: T,
2461
- service: Context.Tag.Service<T>
2462
- ): <OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>(
2459
+ <I, S>(tag: Context.Tag<I, S>, service: Types.NoInfer<S>): <OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>(
2463
2460
  self: Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>
2464
- ) => Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Exclude<Env, Context.Tag.Identifier<T>>>
2461
+ ) => Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Exclude<Env, I>>
2465
2462
  /**
2466
2463
  * Provides the effect with the single service it requires. If the effect
2467
2464
  * requires more than one service use `provideContext` instead.
@@ -2469,11 +2466,11 @@ export const provideService: {
2469
2466
  * @since 2.0.0
2470
2467
  * @category context
2471
2468
  */
2472
- <OutElem, InElem, OutErr, InErr, OutDone, InDone, Env, T extends Context.Tag<any, any>>(
2469
+ <OutElem, InElem, OutErr, InErr, OutDone, InDone, Env, I, S>(
2473
2470
  self: Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>,
2474
- tag: T,
2475
- service: Context.Tag.Service<T>
2476
- ): Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Exclude<Env, Context.Tag.Identifier<T>>>
2471
+ tag: Context.Tag<I, S>,
2472
+ service: Types.NoInfer<S>
2473
+ ): Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Exclude<Env, I>>
2477
2474
  } = channel.provideService
2478
2475
 
2479
2476
  /**
@@ -2829,23 +2826,23 @@ export const updateService: {
2829
2826
  * @since 2.0.0
2830
2827
  * @category context
2831
2828
  */
2832
- <T extends Context.Tag<any, any>>(
2833
- tag: T,
2834
- f: (resource: Context.Tag.Service<T>) => Context.Tag.Service<T>
2829
+ <I, S>(
2830
+ tag: Context.Tag<I, S>,
2831
+ f: (resource: Types.NoInfer<S>) => Types.NoInfer<S>
2835
2832
  ): <OutElem, OutErr, InErr, OutDone, InDone, R>(
2836
2833
  self: Channel<OutElem, unknown, OutErr, InErr, OutDone, InDone, R>
2837
- ) => Channel<OutElem, unknown, OutErr, InErr, OutDone, InDone, T | R>
2834
+ ) => Channel<OutElem, unknown, OutErr, InErr, OutDone, InDone, I | R>
2838
2835
  /**
2839
2836
  * Updates a service in the context of this channel.
2840
2837
  *
2841
2838
  * @since 2.0.0
2842
2839
  * @category context
2843
2840
  */
2844
- <OutElem, OutErr, InErr, OutDone, InDone, R, T extends Context.Tag<any, any>>(
2841
+ <OutElem, OutErr, InErr, OutDone, InDone, R, I, S>(
2845
2842
  self: Channel<OutElem, unknown, OutErr, InErr, OutDone, InDone, R>,
2846
- tag: T,
2847
- f: (resource: Context.Tag.Service<T>) => Context.Tag.Service<T>
2848
- ): Channel<OutElem, unknown, OutErr, InErr, OutDone, InDone, R | T>
2843
+ tag: Context.Tag<I, S>,
2844
+ f: (resource: Types.NoInfer<S>) => Types.NoInfer<S>
2845
+ ): Channel<OutElem, unknown, OutErr, InErr, OutDone, InDone, I | R>
2849
2846
  } = channel.updateService
2850
2847
 
2851
2848
  /**
package/src/DateTime.ts CHANGED
@@ -443,6 +443,23 @@ export const unsafeNow: LazyArg<Utc> = Internal.unsafeNow
443
443
  // time zones
444
444
  // =============================================================================
445
445
 
446
+ /**
447
+ * For a `DateTime` returns a new `DateTime.Utc`.
448
+ *
449
+ * @since 3.13.0
450
+ * @category time zones
451
+ * @example
452
+ * ```ts
453
+ * import { DateTime } from "effect"
454
+ *
455
+ * const now = DateTime.unsafeMakeZoned({ year: 2024 }, { timeZone: "Europe/London" })
456
+ *
457
+ * // set as UTC
458
+ * const utc: DateTime.Utc = DateTime.toUtc(now)
459
+ * ```
460
+ */
461
+ export const toUtc: (self: DateTime) => Utc = Internal.toUtc
462
+
446
463
  /**
447
464
  * Set the time zone of a `DateTime`, returning a new `DateTime.Zoned`.
448
465
  *
@@ -462,10 +479,6 @@ export const unsafeNow: LazyArg<Utc> = Internal.unsafeNow
462
479
  * ```
463
480
  */
464
481
  export const setZone: {
465
- // =============================================================================
466
- // time zones
467
- // =============================================================================
468
-
469
482
  /**
470
483
  * Set the time zone of a `DateTime`, returning a new `DateTime.Zoned`.
471
484
  *
@@ -490,10 +503,6 @@ export const setZone: {
490
503
  readonly adjustForTimeZone?: boolean | undefined
491
504
  }
492
505
  ): (self: DateTime) => Zoned
493
- // =============================================================================
494
- // time zones
495
- // =============================================================================
496
-
497
506
  /**
498
507
  * Set the time zone of a `DateTime`, returning a new `DateTime.Zoned`.
499
508
  *
package/src/Differ.ts CHANGED
@@ -15,6 +15,7 @@ import * as HashMapPatch from "./internal/differ/hashMapPatch.js"
15
15
  import * as HashSetPatch from "./internal/differ/hashSetPatch.js"
16
16
  import * as OrPatch from "./internal/differ/orPatch.js"
17
17
  import * as ReadonlyArrayPatch from "./internal/differ/readonlyArrayPatch.js"
18
+ import type { Pipeable } from "./Pipeable.js"
18
19
  import type * as Types from "./Types.js"
19
20
 
20
21
  /**
@@ -48,7 +49,7 @@ export type TypeId = typeof TypeId
48
49
  * @since 2.0.0
49
50
  * @category models
50
51
  */
51
- export interface Differ<in out Value, in out Patch> {
52
+ export interface Differ<in out Value, in out Patch> extends Pipeable {
52
53
  readonly [TypeId]: {
53
54
  readonly _V: Types.Invariant<Value>
54
55
  readonly _P: Types.Invariant<Patch>
package/src/Duration.ts CHANGED
@@ -993,3 +993,150 @@ export const format = (self: DurationInput): string => {
993
993
 
994
994
  return pieces.join(" ")
995
995
  }
996
+
997
+ /**
998
+ * Formats a Duration into an ISO8601 duration string.
999
+ *
1000
+ * The ISO8601 duration format is generally specified as P[n]Y[n]M[n]DT[n]H[n]M[n]S. However, since
1001
+ * the `Duration` type does not support years or months, this function will only output the days, hours,
1002
+ * minutes and seconds. Thus, the effective format is P[n]DT[n]H[n]M[n]S.
1003
+ *
1004
+ * Milliseconds and nanoseconds are expressed as fractional seconds.
1005
+ *
1006
+ * @throws `RangeError` If the duration is not finite.
1007
+ *
1008
+ * @example
1009
+ * ```ts
1010
+ * import { Duration } from "effect"
1011
+ *
1012
+ * Duration.unsafeFormatIso(Duration.days(1)) // => "P1D"
1013
+ * Duration.unsafeFormatIso(Duration.minutes(90)) // => "PT1H30M"
1014
+ * Duration.unsafeFormatIso(Duration.millis(1500)) // => "PT1.5S"
1015
+ * ```
1016
+ *
1017
+ * @since 3.13.0
1018
+ * @category conversions
1019
+ */
1020
+ export const unsafeFormatIso = (self: DurationInput): string => {
1021
+ const duration = decode(self)
1022
+ if (!isFinite(duration)) {
1023
+ throw new RangeError("Cannot format infinite duration")
1024
+ }
1025
+
1026
+ const fragments = []
1027
+ const {
1028
+ days,
1029
+ hours,
1030
+ millis,
1031
+ minutes,
1032
+ nanos,
1033
+ seconds
1034
+ } = parts(duration)
1035
+
1036
+ let rest = days
1037
+ if (rest >= 365) {
1038
+ const years = Math.floor(rest / 365)
1039
+ rest %= 365
1040
+ fragments.push(`${years}Y`)
1041
+ }
1042
+
1043
+ if (rest >= 30) {
1044
+ const months = Math.floor(rest / 30)
1045
+ rest %= 30
1046
+ fragments.push(`${months}M`)
1047
+ }
1048
+
1049
+ if (rest >= 7) {
1050
+ const weeks = Math.floor(rest / 7)
1051
+ rest %= 7
1052
+ fragments.push(`${weeks}W`)
1053
+ }
1054
+
1055
+ if (rest > 0) {
1056
+ fragments.push(`${rest}D`)
1057
+ }
1058
+
1059
+ if (hours !== 0 || minutes !== 0 || seconds !== 0 || millis !== 0 || nanos !== 0) {
1060
+ fragments.push("T")
1061
+
1062
+ if (hours !== 0) {
1063
+ fragments.push(`${hours}H`)
1064
+ }
1065
+
1066
+ if (minutes !== 0) {
1067
+ fragments.push(`${minutes}M`)
1068
+ }
1069
+
1070
+ if (seconds !== 0 || millis !== 0 || nanos !== 0) {
1071
+ const total = BigInt(seconds) * bigint1e9 + BigInt(millis) * bigint1e6 + BigInt(nanos)
1072
+ const str = (Number(total) / 1e9).toFixed(9).replace(/\.?0+$/, "")
1073
+ fragments.push(`${str}S`)
1074
+ }
1075
+ }
1076
+
1077
+ return `P${fragments.join("") || "T0S"}`
1078
+ }
1079
+
1080
+ /**
1081
+ * Formats a Duration into an ISO8601 duration string.
1082
+ *
1083
+ * Months are assumed to be 30 days and years are assumed to be 365 days.
1084
+ *
1085
+ * Returns `Option.none()` if the duration is infinite.
1086
+ *
1087
+ * @example
1088
+ * ```ts
1089
+ * import { Duration, Option } from "effect"
1090
+ *
1091
+ * Duration.formatIso(Duration.days(1)) // => Option.some("P1D")
1092
+ * Duration.formatIso(Duration.minutes(90)) // => Option.some("PT1H30M")
1093
+ * Duration.formatIso(Duration.millis(1500)) // => Option.some("PT1.5S")
1094
+ * Duration.formatIso(Duration.infinity) // => Option.none()
1095
+ * ```
1096
+ *
1097
+ * @since 3.13.0
1098
+ * @category conversions
1099
+ */
1100
+ export const formatIso = (self: DurationInput): Option.Option<string> => {
1101
+ const duration = decode(self)
1102
+ return isFinite(duration) ? Option.some(unsafeFormatIso(duration)) : Option.none()
1103
+ }
1104
+
1105
+ /**
1106
+ * Parses an ISO8601 duration string into a `Duration`.
1107
+ *
1108
+ * Months are assumed to be 30 days and years are assumed to be 365 days.
1109
+ *
1110
+ * @example
1111
+ * ```ts
1112
+ * import { Duration, Option } from "effect"
1113
+ *
1114
+ * Duration.fromIso("P1D") // => Option.some(Duration.days(1))
1115
+ * Duration.fromIso("PT1H") // => Option.some(Duration.hours(1))
1116
+ * Duration.fromIso("PT1M") // => Option.some(Duration.minutes(1))
1117
+ * Duration.fromIso("PT1.5S") // => Option.some(Duration.seconds(1.5))
1118
+ * ```
1119
+ *
1120
+ * @since 3.13.0
1121
+ * @category conversions
1122
+ */
1123
+ export const fromIso = (iso: string): Option.Option<Duration> => {
1124
+ const result = DURATION_ISO_REGEX.exec(iso)
1125
+ if (result == null) {
1126
+ return Option.none()
1127
+ }
1128
+
1129
+ const [years, months, weeks, days, hours, mins, secs] = result.slice(1, 8).map((_) => _ ? Number(_) : 0)
1130
+ const value = years * 365 * 24 * 60 * 60 +
1131
+ months * 30 * 24 * 60 * 60 +
1132
+ weeks * 7 * 24 * 60 * 60 +
1133
+ days * 24 * 60 * 60 +
1134
+ hours * 60 * 60 +
1135
+ mins * 60 +
1136
+ secs
1137
+
1138
+ return Option.some(seconds(value))
1139
+ }
1140
+
1141
+ const DURATION_ISO_REGEX =
1142
+ /^P(?!$)(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)W)?(?:(\d+)D)?(?:T(?!$)(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d+)?)S)?)?$/