11// ignore_for_file: public_member_api_docs
22// TODO(medz): Add code comments
33
4+ import 'dart:async' ;
5+
46import 'package:meta/meta.dart' ;
57import 'package:solidart/deps/preset.dart' as preset;
68import 'package:solidart/deps/system.dart' as system;
79
810typedef ValueComparator <T > = bool Function (T ? a, T ? b);
911typedef ValueGetter <T > = T Function ();
1012typedef VoidCallback = ValueGetter <void >;
13+ typedef DelayEffectCallback =
14+ ValueGetter <FutureOr <void >> Function (
15+ T Function <T >(T Function () callback) on ,
16+ );
1117
1218sealed class Option <T > {
1319 const Option ();
@@ -294,7 +300,19 @@ class Computed<T> extends preset.ComputedNode<T>
294300class Effect extends preset.EffectNode
295301 with DisposableMixin
296302 implements Disposable , Configuration {
297- Effect (
303+ factory Effect (
304+ VoidCallback callback, {
305+ bool ? autoDispose,
306+ String ? name,
307+ bool ? detach,
308+ }) => Effect .manual (
309+ callback,
310+ autoDispose: autoDispose,
311+ name: name,
312+ detach: detach,
313+ )..run ();
314+
315+ Effect .manual (
298316 VoidCallback callback, {
299317 bool ? autoDispose,
300318 String ? name,
@@ -306,18 +324,44 @@ class Effect extends preset.EffectNode
306324 fn: callback,
307325 flags:
308326 system.ReactiveFlags .watching | system.ReactiveFlags .recursedCheck,
309- ) {
310- final prevSub = preset.setActiveSub (this );
311- if (prevSub != null && ! this .detach) {
312- preset.link (this , prevSub, 0 );
313- }
327+ );
314328
315- try {
316- callback ();
317- } finally {
318- preset.activeSub = prevSub;
319- flags & = ~ system.ReactiveFlags .recursedCheck;
329+ // TODO(nank1ro): How about this plan?
330+ factory Effect .delay (
331+ DelayEffectCallback factory , {
332+ required Duration duration,
333+ bool ? autoDispose,
334+ String ? name,
335+ bool ? detach,
336+ bool eager = true ,
337+ }) {
338+ late final Effect effect;
339+ T on < T > (T Function () callback) {
340+ final prevSub = preset.setActiveSub (effect);
341+ try {
342+ return callback ();
343+ } finally {
344+ preset.activeSub = prevSub;
345+ effect.flags & = ~ system.ReactiveFlags .recursedCheck;
346+ }
320347 }
348+
349+ final callback = factory (on );
350+ Timer ? timer;
351+ effect = Effect .manual (
352+ autoDispose: autoDispose,
353+ name: name,
354+ detach: detach,
355+ () {
356+ timer? .cancel ();
357+ timer = .new (duration, () {
358+ unawaited (Future .microtask (callback))
359+ });
360+ },
361+ );
362+
363+ if (eager) effect.run ();
364+ return effect;
321365 }
322366
323367 @override
@@ -328,6 +372,20 @@ class Effect extends preset.EffectNode
328372
329373 final bool detach;
330374
375+ void run () {
376+ final prevSub = preset.setActiveSub (this );
377+ if (! detach && prevSub != null ) {
378+ preset.link (this , prevSub, 0 );
379+ }
380+
381+ try {
382+ fn ();
383+ } finally {
384+ preset.activeSub = prevSub;
385+ flags & = ~ system.ReactiveFlags .recursedCheck;
386+ }
387+ }
388+
331389 @override
332390 void dispose () {
333391 if (isDisposed) return ;
0 commit comments