Skip to content

v1.1.3 - Fix SignalEffectException with Computed Signal Pattern

Choose a tag to compare

@pillowsoft pillowsoft released this 02 Jan 10:57
· 16 commits to main since this release

πŸ› Bug Fixes

  • Fixed SignalEffectException during magic link authentication - Resolved critical architectural issue with reactive cycles
  • Converted authenticationStatus to computed signal pattern - Proper Signals architecture implementation
  • Eliminated reactive cycles during batch operations - No more nested batch scenarios

What Changed

This patch release fixes a critical architectural anti-pattern where DatabaseService used effect() + signal writes instead of the computed() pattern. This violated Signals architecture by writing to signals inside effects during active batch operations.

The Problem Chain (Fixed)

  1. User authenticates β†’ batch() wraps signal updates in AuthenticationService
  2. InstantDB propagates change β†’ _db.auth.currentUser signal updates
  3. DatabaseService effect() triggers
  4. Effect reads signal and WRITES to authenticationStatus signal
  5. πŸ’₯ Exception: Writing to signal inside effect during active batch

The Solution

The authenticationStatus is now a computed signal that derives its value directly from InstantDB's auth state:

authenticationStatus = computed(() {
  final user = _db?.auth.currentUser.value;
  return user != null
      ? AuthenticationStatus.authenticated
      : AuthenticationStatus.unauthenticated;
});

This follows proper Signals architectural best practices:

  • βœ… No signal mutation inside effects
  • βœ… Computed signals derive values reactively
  • βœ… No reactive cycles or nested batch scenarios
  • βœ… Authentication status updates automatically when InstantDB auth state changes

Files Changed

  • lib/src/services/database_service.dart - Converted to computed signal pattern
  • pubspec.yaml - Version 1.1.3
  • CHANGELOG.md - Release notes

Why v1.1.2 Batch Fix Wasn't Enough

v1.1.2 fixed direct sequential signal writes in AuthenticationService, but didn't address the deeper architectural issue in DatabaseService. The batch() in AuthenticationService triggered DatabaseService effect, which created nested batch scenarios by writing to signals.

Full Changelog

See CHANGELOG.md for complete details.