Repository navigation
2.2.0 - Aug 27, 2026
·
29 commits
to master
since this release
Immutable
release. Only release title and notes can be modified.
https://pub.dev/packages/dart_either/versions/2.2.0
Either
- Side-effect hooks
- Added
onLeftandonRight; each runs an action on one side and returns
the originalEither. - Deprecated aliases remain:
tapLeft→onLeft,tap→onRight.
- Added
- Right-side predicate
- Added
isRightAndto match aRightvalue with a predicate. existsremains as a deprecated alias.
- Added
- Nullable extraction
- Added
getOrNullforRightandleftOrNullforLeft. orNullremains as a deprecated alias ofgetOrNull.
- Added
- Fallback values
- Added eager
getOrDefault(value). - Deprecated lazy
getOrElse(() => value); usegetOrDefaultfor an eager
fallback orgetOrHandle((left) => value)for a lazy, left-aware fallback.
- Added eager
- Composition
combine: combine matching sides; otherwise return the soleLeft.flatten: convertEither<L, Either<L, R>>toEither<L, R>.merge: extract the value fromEither<T, T>.
EitherEffect, Either.binding, and Either.futureBinding
- Direct short-circuit
- Added
effect.raise(left)to exit the owning scope withLeft(left). - It avoids an intermediate
Leftand returnsNever, so it works in
expressions such asnullable ?? effect.raise('missing'). ensureandensureNotNullnow delegate their short-circuit paths to
raise.
- Added
- Variance-safe capability
- Reworked
EitherEffect<L>from a covariant public class into an opaque,
contravariant, scope-bound capability. - Unsafe widening that previously compiled is now rejected; safe narrowing
is supported. bindmoved from an instance member toBindEitherEffectExtension.
Standard unprefixed imports keepeffect.bind(either)unchanged. Prefixed
imports must use the extension override; selective imports must include the
extension.
- Reworked
- Scope lifetime
- Capabilities are now revoked when their sync or async binding scope ends.
- Reusing a captured capability afterward throws
StateError. - Swallowing a scope's short-circuit signal and then completing normally now
throwsStateErrorinstead of producingRight.
Import migration for EitherEffect.bind
The usual unprefixed package import keeps the existing call syntax. With a
prefixed import, invoke the named extension explicitly:
import 'package:dart_either/dart_either.dart' as de;
final result = de.Either<String, int>.binding((effect) {
return de.BindEitherEffectExtension(effect).bind(
de.Either<String, int>.right(1),
);
});For a selective unprefixed import, include BindEitherEffectExtension in the
show list. The Dart SDK constraint remains >=3.0.0 <4.0.0.
Documentation and verification
- Updated the README, runnable examples, API docs, variance guidance, and
binding-scope docs. - Added regression coverage for:
- new APIs and deprecated aliases;
- covariance widening and rejected external
EitherEffectconstruction; - nested sync/async scopes, capability revocation, and intercepted
short-circuits.
- CI now runs the complete suite on every configured Dart SDK and collects
stable-SDK coverage.
Full Changelog: 2.1.0...2.2.0