PendingHook constructor

PendingHook(
  1. ResolvedHook hook, {
  2. required Logger logger,
})

Implementation

factory PendingHook(
  ResolvedHook hook, {
  required Logger logger,
}) {
  final killCompleter = Completer<void>();
  final completedTasks = <int>{};
  final startedTasks = <int>{};

  Iterable<(PendingTask, TaskRunner)> tasks() sync* {
    for (final task in hook.tasks) {
      final resolving = PendingTask(
        files: task.files,
        resolvedTask: task,
        completedTasks: completedTasks,
        startedTasks: startedTasks,
        isHalted: () => killCompleter.isCompleted,
      );

      final runner = TaskRunner(
        task: resolving,
        logger: logger,
        completeTask: (finished, code) {
          final pending = switch (resolving.taskMap[finished.id]) {
            final task? => task,
            _ when resolving.id == finished.id => resolving,
            _ => null,
          };

          final task = hook.tasksById[finished.id];

          if (task == null || pending == null) {
            logger.delayed(
              'This is not expected, please consider reporting this issue.',
            );
            final errorName = switch ((task, pending)) {
              (null, null) => 'Task and pending task',
              (null, _) => 'Task',
              (_, null) => 'Pending task (index: ${task?.index})',
              _ => 'Unknown',
            };
            throw StateError('$errorName ${finished.id} not found');
          }

          pending.code = code;
          completedTasks.add(task.index);
          startedTasks.remove(task.index);
        },
        startTask: (started) {
          final task = hook.tasksById[started.id];
          if (task == null) {
            logger.delayed(
              'This is not expected, please consider reporting this issue.',
            );

            throw StateError('Tasks ${started.id} not found');
          }

          startedTasks.add(task.index);
        },
      );

      yield (resolving, runner);
    }
  }

  final mappedTasks = {
    for (final (task, runner) in [...tasks()])
      task.id: (task: task, runner: runner),
  };

  return PendingHook._(
    mappedTasks,
    logger: logger,
    killCompleter: killCompleter,
    completedTasks: completedTasks,
    startedTasks: startedTasks,
  );
}