fetch method

Future<T> fetch({
  1. bool force = false,
})

Fetch or refetch data

Implementation

Future<T> fetch({bool force = false}) async {
  // 1. Check enabled state (Priority 1)
  if (!enabled.value && !force) {
    if (hasData) return data.value!;
    return Future.error('Query is disabled');
  }

  // 2. Check Offline Status (Automatic Pause) (Priority 2)
  // If we are offline and mode is NOT 'always', we pause.
  final shouldPauseForNetwork = config.networkMode != NetworkMode.always &&
      !ZenQueryCache.instance.isOnline;

  if (shouldPauseForNetwork) {
    if (config.networkMode == NetworkMode.offlineFirst &&
        hasData &&
        !isStale) {
      return data.value!;
    }

    if (fetchStatus.value != ZenQueryFetchStatus.paused) {
      ZenLogger.logDebug('Query $queryKey paused (offline)');
      fetchStatus.value = ZenQueryFetchStatus.paused;
      update();
    }

    if (hasData) return data.value!;
    throw const ZenOfflineException('Query paused due to network connection');
  }

  // 3. Check Manual Pause (Sticky) (Priority 3)
  // If manually paused, stay paused unless forced (or network check overrode it)
  if (fetchStatus.value == ZenQueryFetchStatus.paused && !force) {
    if (hasData) return data.value!;
    return Future.error('Query is paused');
  }

  // 4. Return cached data if available and not stale
  if (!force && hasData && !isStale) {
    return data.value!;
  }

  // Deduplicate concurrent requests
  if (_currentFetch != null) {
    return _currentFetch!;
  }

  // Start fetch operation
  _currentFetch = performFetch();

  try {
    final result = await _currentFetch!;
    return result;
  } finally {
    _currentFetch = null;
  }
}