@@ -6,6 +6,7 @@ import './extension/future_or_extension.dart';
6
6
import './extension/iterable_extension.dart' ;
7
7
import 'unit.dart' as fpdart_unit;
8
8
9
+ part 'async_context.dart' ;
9
10
part 'context.dart' ;
10
11
part 'deferred.dart' ;
11
12
part 'either.dart' ;
@@ -152,18 +153,70 @@ final class Effect<E, L, R> extends IEffect<E, L, R> {
152
153
(_) => f ().then (Right .new ),
153
154
);
154
155
156
+ /// {@category constructors}
157
+ factory Effect .fail (L value) => Effect .from ((_) => Left (Failure (value)));
158
+
159
+ /// {@category constructors}
160
+ factory Effect .failCause (Cause <L > cause) => Effect .from ((_) => Left (cause));
161
+
162
+ /// {@category constructors}
163
+ factory Effect .succeed (R value) => Effect .from ((_) => Right (value));
164
+
155
165
/// {@category constructors}
156
166
factory Effect .lazy (Effect <E , L , R > Function () effect) =>
157
167
Effect .from ((context) => effect ()._unsafeRun (context));
158
168
159
169
/// {@category constructors}
160
- factory Effect .fail (L value) => Effect .from ((_) => Left (Failure (value)));
170
+ factory Effect .async (void Function (AsyncContext <L , R > resume) callback) =>
171
+ Effect .from (
172
+ (context) {
173
+ final asyncContext = AsyncContext <L , R >();
174
+ callback (asyncContext);
175
+ return asyncContext._deferred.wait <E >()._unsafeRun (context);
176
+ },
177
+ );
161
178
162
179
/// {@category constructors}
163
- factory Effect .failCause (Cause <L > cause) => Effect .from ((_) => Left (cause));
180
+ factory Effect .asyncInterrupt (
181
+ Effect <Null , Never , Unit > Function (AsyncContext <L , R > resume) callback,
182
+ ) =>
183
+ Effect .from ((context) {
184
+ final asyncContext = AsyncContext <L , R >();
185
+
186
+ final finalizer = callback (asyncContext);
187
+ if (asyncContext._deferred.unsafeCompleted) {
188
+ return asyncContext._deferred.wait <E >()._unsafeRun (context);
189
+ }
190
+
191
+ final interruption = context.signal.wait <E >().alwaysIgnore (
192
+ finalizer.withEnv <E >(),
193
+ );
194
+
195
+ return asyncContext._deferred
196
+ .wait <E >()
197
+ .race (interruption)
198
+ ._unsafeRun (context.withoutSignal);
199
+ });
164
200
165
201
/// {@category constructors}
166
- factory Effect .succeed (R value) => Effect .from ((_) => Right (value));
202
+ static Effect <E , L , void > sleep <E , L >(Duration duration) =>
203
+ Effect .asyncInterrupt (
204
+ (resume) {
205
+ final timer = Timer (duration, () {
206
+ resume.succeed (null );
207
+ });
208
+
209
+ if (resume._deferred.unsafeCompleted) {
210
+ timer.cancel ();
211
+ return resume._deferred.wait <Null >().match (
212
+ onFailure: (_) => fpdart_unit.unit,
213
+ onSuccess: (_) => fpdart_unit.unit,
214
+ );
215
+ }
216
+
217
+ return Effect .unit ();
218
+ },
219
+ );
167
220
168
221
/// {@category constructors}
169
222
factory Effect .raceAll (Iterable <Effect <E , L , R >> iterable) =>
@@ -189,14 +242,6 @@ final class Effect<E, L, R> extends IEffect<E, L, R> {
189
242
);
190
243
});
191
244
192
- /// {@category constructors}
193
- static Effect <E , L , void > sleep <E , L >(Duration duration) => Effect .from (
194
- (_) => Future .delayed (
195
- duration,
196
- () => const Right (null ),
197
- ),
198
- );
199
-
200
245
/// {@category constructors}
201
246
static Effect <E , Never , Never > die <E >(dynamic defect) => Effect .from (
202
247
(_) => Left (Die .current (defect)),
0 commit comments