hotReload method

Future<void> hotReload(
  1. String moduleId, {
  2. Future<void> onBeforeReload()?,
  3. Future<void> onAfterReload()?,
  4. List<String>? stateKeysToPreserve,
})

Hot reload a module while preserving its state

This method:

  1. Captures the current module state
  2. Calls onBeforeReload (dispose old module)
  3. Calls onAfterReload (initialize new module)
  4. Restores the captured state

Implementation

Future<void> hotReload(
  String moduleId, {
  Future<void> Function()? onBeforeReload,
  Future<void> Function()? onAfterReload,
  List<String>? stateKeysToPreserve,
}) async {
  if (!kDebugMode) {
    AirLogger.warning('HMR is only available in debug mode');
    return;
  }

  AirLogger.info('Starting hot reload', context: {'moduleId': moduleId});

  try {
    // 1. Capture state to preserve
    if (stateKeysToPreserve != null && stateKeysToPreserve.isNotEmpty) {
      final stateToPreserve = <String, dynamic>{};
      for (final key in stateKeysToPreserve) {
        final controller = Air().debugStates[key];
        if (controller != null) {
          stateToPreserve[key] = controller.value;
        }
      }
      preserveState(moduleId, stateToPreserve);
    }

    // 2. Notify listeners before reload
    _notifyListeners(moduleId);

    // 3. Dispose old module
    if (onBeforeReload != null) {
      await onBeforeReload();
    }

    // 4. Initialize new module
    if (onAfterReload != null) {
      await onAfterReload();
    }

    // 5. Restore state
    final preserved = restoreState(moduleId);
    if (preserved != null) {
      for (final entry in preserved.entries) {
        try {
          Air()
              .state(entry.key, initialValue: entry.value)
              .setValue(entry.value, sourceModuleId: moduleId);
        } catch (e) {
          AirLogger.warning(
            'Failed to restore state key',
            context: {'key': entry.key, 'error': e.toString()},
          );
        }
      }
    }

    AirLogger.info('Hot reload completed', context: {'moduleId': moduleId});
  } catch (e, stack) {
    AirLogger.error(
      'Hot reload failed',
      context: {'moduleId': moduleId, 'error': e.toString()},
    );
    if (kDebugMode) {
      debugPrintStack(stackTrace: stack);
    }
    rethrow;
  }
}