33 * @experimental
44 */
55import type { NonEmptyReadonlyArray } from "./Array.js"
6+ import * as Arr from "./Array.js"
67import type * as Context from "./Context.js"
78import * as Effect from "./Effect.js"
89import { dual } from "./Function.js"
@@ -11,6 +12,7 @@ import * as Layer from "./Layer.js"
1112import type { Pipeable } from "./Pipeable.js"
1213import { pipeArguments } from "./Pipeable.js"
1314import type * as Schedule from "./Schedule.js"
15+ import type * as Types from "./Types.js"
1416
1517/**
1618 * @since 3.16.0
@@ -45,27 +47,32 @@ export const isExecutionPlan: (u: unknown) => u is ExecutionPlan<unknown, unknow
4547 * declare const layerBad: Layer.Layer<AiLanguageModel.AiLanguageModel>
4648 * declare const layerGood: Layer.Layer<AiLanguageModel.AiLanguageModel>
4749 *
48- * const ThePlan = ExecutionPlan.make({
49- * // First try with the bad layer 2 times with a 3 second delay between attempts
50- * provide: layerBad,
51- * attempts: 2,
52- * schedule: Schedule.spaced(3000)
53- * }).pipe(
50+ * const ThePlan = ExecutionPlan.make(
51+ * {
52+ * // First try with the bad layer 2 times with a 3 second delay between attempts
53+ * provide: layerBad,
54+ * attempts: 2,
55+ * schedule: Schedule.spaced(3000)
56+ * },
5457 * // Then try with the bad layer 3 times with a 1 second delay between attempts
55- * ExecutionPlan.orElse( {
58+ * {
5659 * provide: layerBad,
5760 * attempts: 3,
5861 * schedule: Schedule.spaced(1000)
59- * }) ,
62+ * },
6063 * // Finally try with the good layer.
6164 * //
6265 * // If `attempts` is omitted, the plan will only attempt once, unless a schedule is provided.
63- * ExecutionPlan.orElse( {
66+ * {
6467 * provide: layerGood
65- * })
68+ * }
6669 * )
6770 *
68- * declare const effect: Effect.Effect<void, never, AiLanguageModel.AiLanguageModel>
71+ * declare const effect: Effect.Effect<
72+ * void,
73+ * never,
74+ * AiLanguageModel.AiLanguageModel
75+ * >
6976 * const withPlan: Effect.Effect<void> = Effect.withExecutionPlan(effect, ThePlan)
7077 * ```
7178 *
@@ -76,9 +83,9 @@ export const isExecutionPlan: (u: unknown) => u is ExecutionPlan<unknown, unknow
7683export interface ExecutionPlan < in out Provides , in In = unknown , out E = never , out R = never > extends Pipeable {
7784 readonly [ TypeId ] : TypeId
7885 readonly steps : NonEmptyReadonlyArray < {
79- readonly schedule ?: Schedule . Schedule < unknown , In , R >
86+ readonly schedule ?: Schedule . Schedule < unknown , In , R > | undefined
8087 readonly attempts ?: number | undefined
81- readonly while ?: ( input : In ) => Effect . Effect < boolean , E , R >
88+ readonly while ?: ( ( input : In ) => Effect . Effect < boolean , E , R > ) | undefined
8289 readonly provide : Context . Context < Provides > | Layer . Layer < Provides , E , R >
8390 } >
8491 readonly withRequirements : Effect . Effect < ExecutionPlan < Provides , In , E > , never , R >
@@ -95,27 +102,32 @@ export interface ExecutionPlan<in out Provides, in In = unknown, out E = never,
95102 * declare const layerBad: Layer.Layer<AiLanguageModel.AiLanguageModel>
96103 * declare const layerGood: Layer.Layer<AiLanguageModel.AiLanguageModel>
97104 *
98- * const ThePlan = ExecutionPlan.make({
99- * // First try with the bad layer 2 times with a 3 second delay between attempts
100- * provide: layerBad,
101- * attempts: 2,
102- * schedule: Schedule.spaced(3000)
103- * }).pipe(
105+ * const ThePlan = ExecutionPlan.make(
106+ * {
107+ * // First try with the bad layer 2 times with a 3 second delay between attempts
108+ * provide: layerBad,
109+ * attempts: 2,
110+ * schedule: Schedule.spaced(3000)
111+ * },
104112 * // Then try with the bad layer 3 times with a 1 second delay between attempts
105- * ExecutionPlan.orElse( {
113+ * {
106114 * provide: layerBad,
107115 * attempts: 3,
108116 * schedule: Schedule.spaced(1000)
109- * }) ,
117+ * },
110118 * // Finally try with the good layer.
111119 * //
112120 * // If `attempts` is omitted, the plan will only attempt once, unless a schedule is provided.
113- * ExecutionPlan.orElse( {
121+ * {
114122 * provide: layerGood
115- * })
123+ * }
116124 * )
117125 *
118- * declare const effect: Effect.Effect<void, never, AiLanguageModel.AiLanguageModel>
126+ * declare const effect: Effect.Effect<
127+ * void,
128+ * never,
129+ * AiLanguageModel.AiLanguageModel
130+ * >
119131 * const withPlan: Effect.Effect<void> = Effect.withExecutionPlan(effect, ThePlan)
120132 * ```
121133 *
@@ -124,40 +136,60 @@ export interface ExecutionPlan<in out Provides, in In = unknown, out E = never,
124136 * @experimental
125137 */
126138export const make = <
127- Provides ,
128- Out ,
129- WhileIn = unknown ,
130- SIn = unknown ,
131- LE = never ,
132- LR = never ,
133- WhileE = never ,
134- WhileR = never ,
135- SR = never
136- > ( options : {
137- readonly provide : Context . Context < Provides > | Layer . Layer < Provides , LE , LR >
138- readonly attempts ?: number | undefined
139- readonly while ?:
140- | ( ( input : WhileIn ) => boolean | Effect . Effect < boolean , WhileE , WhileR > )
141- | undefined
142- readonly schedule ?: Schedule . Schedule < Out , SIn , SR > | undefined
143- } ) : ExecutionPlan < Provides , WhileIn & SIn , LE | WhileE , LR | SR | WhileR > => {
144- if ( options . attempts && options . attempts < 1 ) {
145- throw new Error ( "ExecutionPlan.make: attempts must be greater than 0" )
146- }
147- return makeProto ( [
148- {
149- schedule : options . schedule ,
150- attempts : options . attempts ,
151- while : options . while
152- ? ( input : WhileIn ) =>
139+ const Steps extends NonEmptyReadonlyArray < make . Step >
140+ > ( ... steps : Steps & { [ K in keyof Steps ] : make . Step } ) : ExecutionPlan <
141+ Steps [ number ] [ "provide" ] extends Context . Context < infer Provides > | Layer . Layer < infer Provides , infer _E , infer _R >
142+ ? Provides
143+ : never ,
144+ Types . UnionToIntersection <
145+ | ( Steps [ number ] [ "while" ] extends ( input : infer In ) => any ? In : never )
146+ | ( Steps [ number ] [ "schedule" ] extends Schedule . Schedule < infer _Out , infer In , infer _R > ? In : never )
147+ > ,
148+ | ( Steps [ number ] [ "provide" ] extends Layer . Layer < infer _P , infer _E , infer _R > ? _E
149+ : never )
150+ | ( Steps [ number ] [ "while" ] extends ( input : infer _I ) => Effect . Effect < infer _A , infer _E , infer _R > ? _E : never ) ,
151+ | ( Steps [ number ] [ "provide" ] extends Layer . Layer < infer _P , infer _E , infer _R > ? _R
152+ : never )
153+ | ( Steps [ number ] [ "while" ] extends ( input : infer _I ) => Effect . Effect < infer _A , infer _E , infer _R > ? _R : never )
154+ | ( Steps [ number ] [ " schedule" ] extends Schedule . Schedule < infer _Out , infer _In , infer _R > ? _R : never )
155+ > =>
156+ makeProto ( Arr . map ( steps as Steps , ( step ) => {
157+ if ( step . attempts && step . attempts < 1 ) {
158+ throw new Error ( "ExecutionPlan.make: step.attempts must be greater than 0" )
159+ }
160+ return {
161+ schedule : step . schedule ,
162+ attempts : step . attempts ,
163+ while : step . while
164+ ? ( input : any ) =>
153165 Effect . suspend ( ( ) => {
154- const result = options . while ! ( input )
166+ const result = step . while ! ( input )
155167 return typeof result === "boolean" ? Effect . succeed ( result ) : result
156168 } )
157169 : undefined ,
158- provide : options . provide
170+ provide : step . provide
159171 }
160- ] as any )
172+ } ) )
173+
174+ /**
175+ * @since 3.16.0
176+ * @experimental
177+ */
178+ export declare namespace make {
179+ /**
180+ * @since 3.16.0
181+ * @experimental
182+ */
183+ export type Step = {
184+ readonly provide :
185+ | Context . Context < any >
186+ | Context . Context < never >
187+ | Layer . Layer < any , any , any >
188+ | Layer . Layer < never , any , any >
189+ readonly attempts ?: number
190+ readonly while ?: ( input : any ) => boolean | Effect . Effect < boolean , any , any >
191+ readonly schedule ?: Schedule . Schedule < any , any , any >
192+ }
161193}
162194
163195const Proto : Omit < ExecutionPlan < any , any , any , any > , "steps" > = {
@@ -190,81 +222,41 @@ const makeProto = <Provides, In, PlanE, PlanR>(steps: ExecutionPlan<Provides, In
190222export const orElse : {
191223 <
192224 Provides2 ,
193- Out ,
194- Err2 = never ,
195- Req2 = never ,
196225 In2 = unknown ,
197- SIn = unknown ,
198- SR = never ,
199- WhileE = never ,
200- WhileR = never
201- > (
202- options : ExecutionPlan < Provides2 , In2 , Err2 , Req2 > | {
203- readonly provide : Context . Context < Provides2 > | Layer . Layer < Provides2 , Err2 , Req2 >
204- readonly attempts ?: number | undefined
205- readonly while ?:
206- | ( ( input : In2 ) => boolean | Effect . Effect < boolean , WhileE , WhileR > )
207- | undefined
208- readonly schedule ?: Schedule . Schedule < Out , SIn , SR > | undefined
209- }
210- ) : <
226+ Err2 = never ,
227+ Req2 = never
228+ > ( other : ExecutionPlan < Provides2 , In2 , Err2 , Req2 > ) : <
211229 Provides ,
212230 In ,
213231 PlanE ,
214232 PlanR
215233 > (
216234 self : ExecutionPlan < Provides , In , PlanE , PlanR >
217- ) => ExecutionPlan < Provides & Provides2 , In & In2 & SIn , PlanE | Err2 | WhileE , PlanR | Req2 | SR | WhileR >
235+ ) => ExecutionPlan < Provides & Provides2 , In & In2 , PlanE | Err2 , PlanR | Req2 >
218236 <
219237 Provides ,
220238 In ,
221239 PlanE ,
222240 PlanR ,
223241 Provides2 ,
224- Out ,
225- Err2 = never ,
226- Req2 = never ,
227242 In2 = unknown ,
228- SIn = unknown ,
229- SR = never ,
230- WhileE = never ,
231- WhileR = never
243+ Err2 = never ,
244+ Req2 = never
232245 > (
233246 self : ExecutionPlan < Provides , In , PlanE , PlanR > ,
234- options : ExecutionPlan < Provides2 , In2 , Err2 , Req2 > | {
235- readonly provide : Context . Context < Provides2 > | Layer . Layer < Provides2 , Err2 , Req2 >
236- readonly attempts ?: number | undefined
237- readonly while ?:
238- | ( ( input : In2 ) => boolean | Effect . Effect < boolean , WhileE , WhileR > )
239- | undefined
240- readonly schedule ?: Schedule . Schedule < Out , SIn , SR > | undefined
241- }
242- ) : ExecutionPlan < Provides & Provides2 , In & In2 & SIn , PlanE | Err2 | WhileE , PlanR | Req2 | SR | WhileR >
247+ other : ExecutionPlan < Provides2 , In2 , Err2 , Req2 >
248+ ) : ExecutionPlan < Provides & Provides2 , In & In2 , PlanE | Err2 , PlanR | Req2 >
243249} = dual ( 2 , <
244250 Provides ,
245251 In ,
246252 PlanE ,
247253 PlanR ,
248254 Provides2 ,
249- Out ,
250- Err2 = never ,
251- Req2 = never ,
252255 In2 = unknown ,
253- SIn = unknown ,
254- SR = never ,
255- WhileE = never ,
256- WhileR = never
256+ Err2 = never ,
257+ Req2 = never
257258> (
258259 self : ExecutionPlan < Provides , In , PlanE , PlanR > ,
259- options : ExecutionPlan < Provides2 , In2 , Err2 , Req2 > | {
260- readonly provide : Context . Context < Provides2 > | Layer . Layer < Provides2 , Err2 , Req2 >
261- readonly attempts ?: number | undefined
262- readonly while ?:
263- | ( ( input : In2 ) => boolean | Effect . Effect < boolean , WhileE , WhileR > )
264- | undefined
265- readonly schedule ?: Schedule . Schedule < Out , SIn , SR > | undefined
266- }
267- ) : ExecutionPlan < Provides & Provides2 , In & In2 & SIn , PlanE | Err2 | WhileE , PlanR | Req2 | SR | WhileR > => {
268- const other : ExecutionPlan < any , any , any , any > = isExecutionPlan ( options ) ? options : make ( options as any )
269- return makeProto ( self . steps . concat ( other . steps as any ) as any )
270- } )
260+ other : ExecutionPlan < Provides2 , In2 , Err2 , Req2 >
261+ ) : ExecutionPlan < Provides & Provides2 , In & In2 , PlanE | Err2 , PlanR | Req2 > =>
262+ makeProto ( self . steps . concat ( other . steps as any ) as any ) )
0 commit comments