effect 3.15.4 → 3.16.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 (128) hide show
  1. package/ExecutionPlan/package.json +6 -0
  2. package/dist/cjs/Array.js +67 -5
  3. package/dist/cjs/Array.js.map +1 -1
  4. package/dist/cjs/BigDecimal.js +150 -1
  5. package/dist/cjs/BigDecimal.js.map +1 -1
  6. package/dist/cjs/Chunk.js +16 -3
  7. package/dist/cjs/Chunk.js.map +1 -1
  8. package/dist/cjs/Config.js +16 -2
  9. package/dist/cjs/Config.js.map +1 -1
  10. package/dist/cjs/Effect.js +31 -3
  11. package/dist/cjs/Effect.js.map +1 -1
  12. package/dist/cjs/ExecutionPlan.js +108 -0
  13. package/dist/cjs/ExecutionPlan.js.map +1 -0
  14. package/dist/cjs/HashMap.js +18 -1
  15. package/dist/cjs/HashMap.js.map +1 -1
  16. package/dist/cjs/Iterable.js +27 -1
  17. package/dist/cjs/Iterable.js.map +1 -1
  18. package/dist/cjs/LayerMap.js +86 -64
  19. package/dist/cjs/LayerMap.js.map +1 -1
  20. package/dist/cjs/Schedule.js +7 -1
  21. package/dist/cjs/Schedule.js.map +1 -1
  22. package/dist/cjs/Stream.js +15 -2
  23. package/dist/cjs/Stream.js.map +1 -1
  24. package/dist/cjs/index.js +4 -2
  25. package/dist/cjs/index.js.map +1 -1
  26. package/dist/cjs/internal/config.js +18 -1
  27. package/dist/cjs/internal/config.js.map +1 -1
  28. package/dist/cjs/internal/effect/circular.js +1 -4
  29. package/dist/cjs/internal/effect/circular.js.map +1 -1
  30. package/dist/cjs/internal/executionPlan.js +68 -0
  31. package/dist/cjs/internal/executionPlan.js.map +1 -0
  32. package/dist/cjs/internal/hashMap.js +3 -1
  33. package/dist/cjs/internal/hashMap.js.map +1 -1
  34. package/dist/cjs/internal/metric/polling.js +3 -4
  35. package/dist/cjs/internal/metric/polling.js.map +1 -1
  36. package/dist/cjs/internal/schedule.js +66 -25
  37. package/dist/cjs/internal/schedule.js.map +1 -1
  38. package/dist/cjs/internal/stream.js +60 -10
  39. package/dist/cjs/internal/stream.js.map +1 -1
  40. package/dist/cjs/internal/version.js +1 -1
  41. package/dist/dts/Array.d.ts +110 -0
  42. package/dist/dts/Array.d.ts.map +1 -1
  43. package/dist/dts/BigDecimal.d.ts +235 -0
  44. package/dist/dts/BigDecimal.d.ts.map +1 -1
  45. package/dist/dts/Chunk.d.ts +13 -0
  46. package/dist/dts/Chunk.d.ts.map +1 -1
  47. package/dist/dts/Config.d.ts +38 -1
  48. package/dist/dts/Config.d.ts.map +1 -1
  49. package/dist/dts/Effect.d.ts +99 -27
  50. package/dist/dts/Effect.d.ts.map +1 -1
  51. package/dist/dts/ExecutionPlan.d.ts +213 -0
  52. package/dist/dts/ExecutionPlan.d.ts.map +1 -0
  53. package/dist/dts/HashMap.d.ts +52 -0
  54. package/dist/dts/HashMap.d.ts.map +1 -1
  55. package/dist/dts/Iterable.d.ts +49 -0
  56. package/dist/dts/Iterable.d.ts.map +1 -1
  57. package/dist/dts/LayerMap.d.ts +79 -72
  58. package/dist/dts/LayerMap.d.ts.map +1 -1
  59. package/dist/dts/Schedule.d.ts +26 -0
  60. package/dist/dts/Schedule.d.ts.map +1 -1
  61. package/dist/dts/Stream.d.ts +57 -2
  62. package/dist/dts/Stream.d.ts.map +1 -1
  63. package/dist/dts/index.d.ts +5 -0
  64. package/dist/dts/index.d.ts.map +1 -1
  65. package/dist/dts/internal/executionPlan.d.ts +2 -0
  66. package/dist/dts/internal/executionPlan.d.ts.map +1 -0
  67. package/dist/dts/internal/hashMap.d.ts.map +1 -1
  68. package/dist/dts/internal/stream.d.ts.map +1 -1
  69. package/dist/esm/Array.js +65 -3
  70. package/dist/esm/Array.js.map +1 -1
  71. package/dist/esm/BigDecimal.js +148 -0
  72. package/dist/esm/BigDecimal.js.map +1 -1
  73. package/dist/esm/Chunk.js +15 -2
  74. package/dist/esm/Chunk.js.map +1 -1
  75. package/dist/esm/Config.js +15 -1
  76. package/dist/esm/Config.js.map +1 -1
  77. package/dist/esm/Effect.js +29 -1
  78. package/dist/esm/Effect.js.map +1 -1
  79. package/dist/esm/ExecutionPlan.js +99 -0
  80. package/dist/esm/ExecutionPlan.js.map +1 -0
  81. package/dist/esm/HashMap.js +17 -0
  82. package/dist/esm/HashMap.js.map +1 -1
  83. package/dist/esm/Iterable.js +26 -0
  84. package/dist/esm/Iterable.js.map +1 -1
  85. package/dist/esm/LayerMap.js +86 -64
  86. package/dist/esm/LayerMap.js.map +1 -1
  87. package/dist/esm/Schedule.js +5 -0
  88. package/dist/esm/Schedule.js.map +1 -1
  89. package/dist/esm/Stream.js +13 -0
  90. package/dist/esm/Stream.js.map +1 -1
  91. package/dist/esm/index.js +5 -0
  92. package/dist/esm/index.js.map +1 -1
  93. package/dist/esm/internal/config.js +16 -0
  94. package/dist/esm/internal/config.js.map +1 -1
  95. package/dist/esm/internal/effect/circular.js +0 -3
  96. package/dist/esm/internal/effect/circular.js.map +1 -1
  97. package/dist/esm/internal/executionPlan.js +59 -0
  98. package/dist/esm/internal/executionPlan.js.map +1 -0
  99. package/dist/esm/internal/hashMap.js +2 -0
  100. package/dist/esm/internal/hashMap.js.map +1 -1
  101. package/dist/esm/internal/metric/polling.js +3 -4
  102. package/dist/esm/internal/metric/polling.js.map +1 -1
  103. package/dist/esm/internal/schedule.js +61 -23
  104. package/dist/esm/internal/schedule.js.map +1 -1
  105. package/dist/esm/internal/stream.js +57 -7
  106. package/dist/esm/internal/stream.js.map +1 -1
  107. package/dist/esm/internal/version.js +1 -1
  108. package/package.json +9 -1
  109. package/src/Array.ts +147 -4
  110. package/src/BigDecimal.ts +355 -0
  111. package/src/Chunk.ts +28 -3
  112. package/src/Config.ts +40 -1
  113. package/src/Effect.ts +145 -36
  114. package/src/ExecutionPlan.ts +302 -0
  115. package/src/HashMap.ts +56 -0
  116. package/src/Iterable.ts +66 -0
  117. package/src/LayerMap.ts +126 -114
  118. package/src/Schedule.ts +32 -0
  119. package/src/Stream.ts +51 -2
  120. package/src/index.ts +6 -0
  121. package/src/internal/config.ts +55 -0
  122. package/src/internal/effect/circular.ts +0 -15
  123. package/src/internal/executionPlan.ts +114 -0
  124. package/src/internal/hashMap.ts +6 -0
  125. package/src/internal/metric/polling.ts +3 -4
  126. package/src/internal/schedule.ts +169 -50
  127. package/src/internal/stream.ts +140 -15
  128. package/src/internal/version.ts +1 -1
@@ -0,0 +1,114 @@
1
+ import type { Effect } from "../Effect.js"
2
+ import * as Either from "../Either.js"
3
+ import type * as Api from "../ExecutionPlan.js"
4
+ import { dual } from "../Function.js"
5
+ import * as Predicate from "../Predicate.js"
6
+ import * as core from "./core.js"
7
+ import * as layer from "./layer.js"
8
+ import * as InternalSchedule from "./schedule.js"
9
+
10
+ /** @internal */
11
+ export const TypeId: Api.TypeId = Symbol.for("effect/ExecutionPlan") as Api.TypeId
12
+
13
+ /** @internal */
14
+ export const isExecutionPlan = (u: unknown): u is Api.ExecutionPlan<any> => Predicate.hasProperty(u, TypeId)
15
+
16
+ /** @internal */
17
+ export const withExecutionPlan: {
18
+ <Input, Provides, PlanE, PlanR>(
19
+ plan: Api.ExecutionPlan<{
20
+ provides: Provides
21
+ input: Input
22
+ error: PlanE
23
+ requirements: PlanR
24
+ }>
25
+ ): <A, E extends Input, R>(effect: Effect<A, E, R>) => Effect<
26
+ A,
27
+ E | PlanE,
28
+ Exclude<R, Provides> | PlanR
29
+ >
30
+ <A, E extends Input, R, Provides, Input, PlanE, PlanR>(
31
+ effect: Effect<A, E, R>,
32
+ plan: Api.ExecutionPlan<{
33
+ provides: Provides
34
+ input: Input
35
+ error: PlanE
36
+ requirements: PlanR
37
+ }>
38
+ ): Effect<
39
+ A,
40
+ E | PlanE,
41
+ Exclude<R, Provides> | PlanR
42
+ >
43
+ } = dual(2, <A, E extends Input, R, Provides, Input, PlanE, PlanR>(
44
+ effect: Effect<A, E, R>,
45
+ plan: Api.ExecutionPlan<{
46
+ provides: Provides
47
+ input: Input
48
+ error: PlanE
49
+ requirements: PlanR
50
+ }>
51
+ ) =>
52
+ core.suspend(() => {
53
+ let i = 0
54
+ let result: Either.Either<A, any> | undefined
55
+ return core.flatMap(
56
+ core.whileLoop({
57
+ while: () => i < plan.steps.length && (result === undefined || Either.isLeft(result)),
58
+ body: () => {
59
+ const step = plan.steps[i]
60
+ let nextEffect: Effect<A, any, any> = layer.effect_provide(effect, step.provide as any)
61
+ if (result) {
62
+ let attempted = false
63
+ const wrapped = nextEffect
64
+ // ensure the schedule is applied at least once
65
+ nextEffect = core.suspend(() => {
66
+ if (attempted) return wrapped
67
+ attempted = true
68
+ return result!
69
+ })
70
+ nextEffect = InternalSchedule.scheduleDefectRefail(
71
+ InternalSchedule.retry_Effect(nextEffect, scheduleFromStep(step, false)!)
72
+ )
73
+ } else {
74
+ const schedule = scheduleFromStep(step, true)
75
+ nextEffect = schedule
76
+ ? InternalSchedule.scheduleDefectRefail(InternalSchedule.retry_Effect(nextEffect, schedule))
77
+ : nextEffect
78
+ }
79
+ return core.either(nextEffect)
80
+ },
81
+ step: (either) => {
82
+ result = either
83
+ i++
84
+ }
85
+ }),
86
+ () => result!
87
+ )
88
+ }))
89
+
90
+ /** @internal */
91
+ export const scheduleFromStep = <Provides, In, PlanE, PlanR>(
92
+ step: Api.ExecutionPlan<{
93
+ provides: Provides
94
+ input: In
95
+ error: PlanE
96
+ requirements: PlanR
97
+ }>["steps"][number],
98
+ first: boolean
99
+ ) => {
100
+ if (!first) {
101
+ return InternalSchedule.fromRetryOptions({
102
+ schedule: step.schedule ? step.schedule : step.attempts ? undefined : InternalSchedule.once,
103
+ times: step.attempts,
104
+ while: step.while
105
+ })
106
+ } else if (step.attempts === 1 || !(step.schedule || step.attempts)) {
107
+ return undefined
108
+ }
109
+ return InternalSchedule.fromRetryOptions({
110
+ schedule: step.schedule,
111
+ while: step.while,
112
+ times: step.attempts ? step.attempts - 1 : undefined
113
+ })
114
+ }
@@ -287,6 +287,12 @@ export const hasHash = Dual.dual<
287
287
  <K, V, K1 extends K>(self: HM.HashMap<K, V>, key: K1, hash: number) => boolean
288
288
  >(3, (self, key, hash) => Option.isSome(getHash(self, key, hash)))
289
289
 
290
+ /** @internal */
291
+ export const hasBy = Dual.dual<
292
+ <K, V>(predicate: (value: NoInfer<V>, key: NoInfer<K>) => boolean) => (self: HM.HashMap<K, V>) => boolean,
293
+ <K, V>(self: HM.HashMap<K, V>, predicate: (value: NoInfer<V>, key: NoInfer<K>) => boolean) => boolean
294
+ >(2, (self, predicate) => Option.isSome(findFirst(self, predicate)))
295
+
290
296
  /** @internal */
291
297
  export const set = Dual.dual<
292
298
  <K, V>(key: K, value: V) => (self: HM.HashMap<K, V>) => HM.HashMap<K, V>,
@@ -7,9 +7,8 @@ import { pipeArguments } from "../../Pipeable.js"
7
7
  import type * as Schedule from "../../Schedule.js"
8
8
  import type * as Scope from "../../Scope.js"
9
9
  import * as core from "../core.js"
10
- import * as circular from "../effect/circular.js"
11
10
  import * as metric from "../metric.js"
12
- import * as schedule from "../schedule.js"
11
+ import * as schedule_ from "../schedule.js"
13
12
 
14
13
  /** @internal */
15
14
  const MetricPollingSymbolKey = "effect/MetricPolling"
@@ -84,7 +83,7 @@ export const launch = dual<
84
83
  pipe(
85
84
  pollAndUpdate(self),
86
85
  core.zipRight(metric.value(self.metric)),
87
- circular.scheduleForked(schedule)
86
+ schedule_.scheduleForked(schedule)
88
87
  ))
89
88
 
90
89
  /** @internal */
@@ -114,7 +113,7 @@ export const retry = dual<
114
113
  return pipeArguments(this, arguments)
115
114
  },
116
115
  metric: self.metric,
117
- poll: schedule.retry_Effect(self.poll, policy)
116
+ poll: schedule_.retry_Effect(self.poll, policy)
118
117
  }))
119
118
 
120
119
  /** @internal */
@@ -8,6 +8,7 @@ import * as Duration from "../Duration.js"
8
8
  import type * as Effect from "../Effect.js"
9
9
  import * as Either from "../Either.js"
10
10
  import * as Equal from "../Equal.js"
11
+ import type * as Fiber from "../Fiber.js"
11
12
  import type { LazyArg } from "../Function.js"
12
13
  import { constVoid, dual, pipe } from "../Function.js"
13
14
  import * as Option from "../Option.js"
@@ -19,10 +20,12 @@ import type * as Schedule from "../Schedule.js"
19
20
  import * as ScheduleDecision from "../ScheduleDecision.js"
20
21
  import * as Interval from "../ScheduleInterval.js"
21
22
  import * as Intervals from "../ScheduleIntervals.js"
23
+ import type { Scope } from "../Scope.js"
22
24
  import type * as Types from "../Types.js"
23
25
  import * as internalCause from "./cause.js"
24
26
  import * as effect from "./core-effect.js"
25
27
  import * as core from "./core.js"
28
+ import { forkScoped } from "./effect/circular.js"
26
29
  import * as ref from "./ref.js"
27
30
 
28
31
  /** @internal */
@@ -45,6 +48,22 @@ export const ScheduleDriverTypeId: Schedule.ScheduleDriverTypeId = Symbol.for(
45
48
  ScheduleDriverSymbolKey
46
49
  ) as Schedule.ScheduleDriverTypeId
47
50
 
51
+ /** @internal */
52
+ const defaultIterationMetadata: Schedule.IterationMetadata = {
53
+ start: 0,
54
+ now: 0,
55
+ input: undefined,
56
+ elapsed: Duration.zero,
57
+ elapsedSincePrevious: Duration.zero,
58
+ recurrence: 0
59
+ }
60
+
61
+ /** @internal */
62
+ export const CurrentIterationMetadata = Context.Reference<Schedule.CurrentIterationMetadata>()(
63
+ "effect/Schedule/CurrentIterationMetadata",
64
+ { defaultValue: () => defaultIterationMetadata }
65
+ )
66
+
48
67
  const scheduleVariance = {
49
68
  /* c8 ignore next */
50
69
  _Out: (_: never) => _,
@@ -80,6 +99,31 @@ class ScheduleImpl<S, Out, In, R> implements Schedule.Schedule<Out, In, R> {
80
99
  }
81
100
  }
82
101
 
102
+ /** @internal */
103
+ const updateInfo = (
104
+ iterationMetaRef: Ref.Ref<Schedule.IterationMetadata>,
105
+ now: number,
106
+ input: unknown
107
+ ) =>
108
+ ref.update(iterationMetaRef, (prev) =>
109
+ (prev.recurrence === 0) ?
110
+ {
111
+ now,
112
+ input,
113
+ recurrence: prev.recurrence + 1,
114
+ elapsed: Duration.zero,
115
+ elapsedSincePrevious: Duration.zero,
116
+ start: now
117
+ } :
118
+ {
119
+ now,
120
+ input,
121
+ recurrence: prev.recurrence + 1,
122
+ elapsed: Duration.millis(now - prev.start),
123
+ elapsedSincePrevious: Duration.millis(now - prev.now),
124
+ start: prev.start
125
+ })
126
+
83
127
  /** @internal */
84
128
  class ScheduleDriverImpl<Out, In, R> implements Schedule.ScheduleDriver<Out, In, R> {
85
129
  [ScheduleDriverTypeId] = scheduleDriverVariance
@@ -106,8 +150,12 @@ class ScheduleDriverImpl<Out, In, R> implements Schedule.ScheduleDriver<Out, In,
106
150
  })
107
151
  }
108
152
 
153
+ iterationMeta = ref.unsafeMake(defaultIterationMetadata)
154
+
109
155
  get reset(): Effect.Effect<void> {
110
- return ref.set(this.ref, [Option.none(), this.schedule.initial])
156
+ return ref.set(this.ref, [Option.none(), this.schedule.initial]).pipe(
157
+ core.zipLeft(ref.set(this.iterationMeta, defaultIterationMetadata))
158
+ )
111
159
  }
112
160
 
113
161
  next(input: In): Effect.Effect<Out, Option.Option<never>, R> {
@@ -122,15 +170,22 @@ class ScheduleDriverImpl<Out, In, R> implements Schedule.ScheduleDriver<Out, In,
122
170
  core.flatMap(([state, out, decision]) => {
123
171
  const setState = ref.set(this.ref, [Option.some(out), state] as const)
124
172
  if (ScheduleDecision.isDone(decision)) {
125
- return core.zipRight(setState, core.fail(Option.none()))
173
+ return setState.pipe(
174
+ core.zipRight(core.fail(Option.none()))
175
+ )
126
176
  }
127
177
  const millis = Intervals.start(decision.intervals) - now
128
178
  if (millis <= 0) {
129
- return core.as(setState, out)
179
+ return setState.pipe(
180
+ core.zipRight(updateInfo(this.iterationMeta, now, input)),
181
+ core.as(out)
182
+ )
130
183
  }
184
+ const duration = Duration.millis(millis)
131
185
  return pipe(
132
186
  setState,
133
- core.zipRight(effect.sleep(Duration.millis(millis))),
187
+ core.zipRight(updateInfo(this.iterationMeta, now, input)),
188
+ core.zipRight(effect.sleep(duration)),
134
189
  core.as(out)
135
190
  )
136
191
  })
@@ -1784,18 +1839,23 @@ class ScheduleDefect<E> {
1784
1839
  const isScheduleDefect = <E = unknown>(u: unknown): u is ScheduleDefect<E> => hasProperty(u, ScheduleDefectTypeId)
1785
1840
  const scheduleDefectWrap = <A, E, R>(self: Effect.Effect<A, E, R>) =>
1786
1841
  core.catchAll(self, (e) => core.die(new ScheduleDefect(e)))
1787
- const scheduleDefectRefail = <A, E, R>(self: Effect.Effect<A, E, R>) =>
1788
- core.catchAllCause(self, (cause) =>
1789
- Option.match(
1790
- internalCause.find(
1791
- cause,
1792
- (_) => internalCause.isDieType(_) && isScheduleDefect<E>(_.defect) ? Option.some(_.defect) : Option.none()
1793
- ),
1794
- {
1795
- onNone: () => core.failCause(cause),
1796
- onSome: (error) => core.fail(error.error)
1797
- }
1798
- ))
1842
+
1843
+ /** @internal */
1844
+ export const scheduleDefectRefailCause = <E>(cause: Cause.Cause<E>) =>
1845
+ Option.match(
1846
+ internalCause.find(
1847
+ cause,
1848
+ (_) => internalCause.isDieType(_) && isScheduleDefect<E>(_.defect) ? Option.some(_.defect) : Option.none()
1849
+ ),
1850
+ {
1851
+ onNone: () => cause,
1852
+ onSome: (error) => internalCause.fail(error.error)
1853
+ }
1854
+ )
1855
+
1856
+ /** @internal */
1857
+ export const scheduleDefectRefail = <A, E, R>(effect: Effect.Effect<A, E, R>) =>
1858
+ core.catchAllCause(effect, (cause) => core.failCause(scheduleDefectRefailCause(cause)))
1799
1859
 
1800
1860
  /** @internal */
1801
1861
  export const repeat_Effect = dual<
@@ -1854,7 +1914,6 @@ export const repeat_combined = dual<{
1854
1914
  const withTimes = options.times ?
1855
1915
  intersect(withUntil, recurs(options.times)).pipe(map((intersectionPair) => intersectionPair[0])) :
1856
1916
  withUntil
1857
-
1858
1917
  return scheduleDefectRefail(repeat_Effect(self, withTimes))
1859
1918
  }
1860
1919
  )
@@ -1874,7 +1933,22 @@ export const repeatOrElse_Effect = dual<
1874
1933
  core.flatMap(driver(schedule), (driver) =>
1875
1934
  core.matchEffect(self, {
1876
1935
  onFailure: (error) => orElse(error, Option.none()),
1877
- onSuccess: (value) => repeatOrElseEffectLoop(self, driver, orElse, value)
1936
+ onSuccess: (value) =>
1937
+ repeatOrElseEffectLoop(
1938
+ effect.provideServiceEffect(
1939
+ self,
1940
+ CurrentIterationMetadata,
1941
+ ref.get(driver.iterationMeta)
1942
+ ),
1943
+ driver,
1944
+ (error, option) =>
1945
+ effect.provideServiceEffect(
1946
+ orElse(error, option),
1947
+ CurrentIterationMetadata,
1948
+ ref.get(driver.iterationMeta)
1949
+ ),
1950
+ value
1951
+ )
1878
1952
  })))
1879
1953
 
1880
1954
  /** @internal */
@@ -1883,8 +1957,8 @@ const repeatOrElseEffectLoop = <A, E, R, R1, B, C, E2, R2>(
1883
1957
  driver: Schedule.ScheduleDriver<B, A, R1>,
1884
1958
  orElse: (error: E, option: Option.Option<B>) => Effect.Effect<C, E2, R2>,
1885
1959
  value: A
1886
- ): Effect.Effect<B | C, E2, R | R1 | R2> => {
1887
- return core.matchEffect(driver.next(value), {
1960
+ ): Effect.Effect<B | C, E2, R | R1 | R2> =>
1961
+ core.matchEffect(driver.next(value), {
1888
1962
  onFailure: () => core.orDie(driver.last),
1889
1963
  onSuccess: (b) =>
1890
1964
  core.matchEffect(self, {
@@ -1892,7 +1966,6 @@ const repeatOrElseEffectLoop = <A, E, R, R1, B, C, E2, R2>(
1892
1966
  onSuccess: (value) => repeatOrElseEffectLoop(self, driver, orElse, value)
1893
1967
  })
1894
1968
  })
1895
- }
1896
1969
 
1897
1970
  /** @internal */
1898
1971
  export const retry_Effect = dual<
@@ -1921,41 +1994,47 @@ export const retry_combined: {
1921
1994
  ): Effect.Retry.Return<R, E, A, O>
1922
1995
  <A, E, R, B, R1>(
1923
1996
  self: Effect.Effect<A, E, R>,
1924
- policy: Schedule.Schedule<B, E, R1>
1997
+ policy: Schedule.Schedule<B, Types.NoInfer<E>, R1>
1925
1998
  ): Effect.Effect<A, E, R1 | R>
1926
1999
  } = dual(
1927
2000
  2,
1928
- (self: Effect.Effect<any, any, any>, options: Effect.Retry.Options<any> | Schedule.Schedule<any, any, any>) => {
2001
+ (
2002
+ self: Effect.Effect<any, any, any>,
2003
+ options: Effect.Retry.Options<any> | Schedule.Schedule<any, any, any>
2004
+ ) => {
1929
2005
  if (isSchedule(options)) {
1930
2006
  return retry_Effect(self, options)
1931
2007
  }
1932
-
1933
- const base = options.schedule ?? forever
1934
- const withWhile = options.while ?
1935
- whileInputEffect(base, (e) => {
1936
- const applied = options.while!(e)
1937
- if (typeof applied === "boolean") {
1938
- return core.succeed(applied)
1939
- }
1940
- return scheduleDefectWrap(applied)
1941
- }) :
1942
- base
1943
- const withUntil = options.until ?
1944
- untilInputEffect(withWhile, (e) => {
1945
- const applied = options.until!(e)
1946
- if (typeof applied === "boolean") {
1947
- return core.succeed(applied)
1948
- }
1949
- return scheduleDefectWrap(applied)
1950
- }) :
1951
- withWhile
1952
- const withTimes = options.times ?
1953
- intersect(withUntil, recurs(options.times)) :
1954
- withUntil
1955
- return scheduleDefectRefail(retry_Effect(self, withTimes))
2008
+ return scheduleDefectRefail(retry_Effect(self, fromRetryOptions(options)))
1956
2009
  }
1957
2010
  )
1958
2011
 
2012
+ /** @internal */
2013
+ export const fromRetryOptions = (options: Effect.Retry.Options<any>): Schedule.Schedule<any, any, any> => {
2014
+ const base = options.schedule ?? forever
2015
+ const withWhile = options.while ?
2016
+ whileInputEffect(base, (e) => {
2017
+ const applied = options.while!(e)
2018
+ if (typeof applied === "boolean") {
2019
+ return core.succeed(applied)
2020
+ }
2021
+ return scheduleDefectWrap(applied)
2022
+ }) :
2023
+ base
2024
+ const withUntil = options.until ?
2025
+ untilInputEffect(withWhile, (e) => {
2026
+ const applied = options.until!(e)
2027
+ if (typeof applied === "boolean") {
2028
+ return core.succeed(applied)
2029
+ }
2030
+ return scheduleDefectWrap(applied)
2031
+ }) :
2032
+ withWhile
2033
+ return options.times ?
2034
+ intersect(withUntil, recurs(options.times)) :
2035
+ withUntil
2036
+ }
2037
+
1959
2038
  /** @internal */
1960
2039
  export const retryOrElse_Effect = dual<
1961
2040
  <A1, E, R1, A2, E2, R2>(
@@ -1970,7 +2049,21 @@ export const retryOrElse_Effect = dual<
1970
2049
  >(3, (self, policy, orElse) =>
1971
2050
  core.flatMap(
1972
2051
  driver(policy),
1973
- (driver) => retryOrElse_EffectLoop(self, driver, orElse)
2052
+ (driver) =>
2053
+ retryOrElse_EffectLoop(
2054
+ effect.provideServiceEffect(
2055
+ self,
2056
+ CurrentIterationMetadata,
2057
+ ref.get(driver.iterationMeta)
2058
+ ),
2059
+ driver,
2060
+ (e, out) =>
2061
+ effect.provideServiceEffect(
2062
+ orElse(e, out),
2063
+ CurrentIterationMetadata,
2064
+ ref.get(driver.iterationMeta)
2065
+ )
2066
+ )
1974
2067
  ))
1975
2068
 
1976
2069
  /** @internal */
@@ -2022,7 +2115,16 @@ export const scheduleFrom_Effect = dual<
2022
2115
  >(3, (self, initial, schedule) =>
2023
2116
  core.flatMap(
2024
2117
  driver(schedule),
2025
- (driver) => scheduleFrom_EffectLoop(self, initial, driver)
2118
+ (driver) =>
2119
+ scheduleFrom_EffectLoop(
2120
+ effect.provideServiceEffect(
2121
+ self,
2122
+ CurrentIterationMetadata,
2123
+ ref.get(driver.iterationMeta)
2124
+ ),
2125
+ initial,
2126
+ driver
2127
+ )
2026
2128
  ))
2027
2129
 
2028
2130
  /** @internal */
@@ -2033,7 +2135,11 @@ const scheduleFrom_EffectLoop = <In, E, R, R2, Out>(
2033
2135
  ): Effect.Effect<Out, E, R | R2> =>
2034
2136
  core.matchEffect(driver.next(initial), {
2035
2137
  onFailure: () => core.orDie(driver.last),
2036
- onSuccess: () => core.flatMap(self, (a) => scheduleFrom_EffectLoop(self, a, driver))
2138
+ onSuccess: () =>
2139
+ core.flatMap(
2140
+ self,
2141
+ (a) => scheduleFrom_EffectLoop(self, a, driver)
2142
+ )
2037
2143
  })
2038
2144
 
2039
2145
  /** @internal */
@@ -2074,3 +2180,16 @@ export const once: Schedule.Schedule<void> = asVoid(recurs(1))
2074
2180
 
2075
2181
  /** @internal */
2076
2182
  export const stop: Schedule.Schedule<void> = asVoid(recurs(0))
2183
+
2184
+ /** @internal */
2185
+ export const scheduleForked = dual<
2186
+ <Out, R2>(
2187
+ schedule: Schedule.Schedule<Out, unknown, R2>
2188
+ ) => <A, E, R>(
2189
+ self: Effect.Effect<A, E, R>
2190
+ ) => Effect.Effect<Fiber.RuntimeFiber<Out, E>, never, R | R2 | Scope>,
2191
+ <A, E, R, Out, R2>(
2192
+ self: Effect.Effect<A, E, R>,
2193
+ schedule: Schedule.Schedule<Out, unknown, R2>
2194
+ ) => Effect.Effect<Fiber.RuntimeFiber<Out, E>, never, R | R2 | Scope>
2195
+ >(2, (self, schedule) => forkScoped(schedule_Effect(self, schedule)))