File size: 1,271 Bytes
f0634fb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation';
import type { Event } from '#/_base/event';
import type { IDisposable } from '#/_base/di/lifecycle';

export type TaskState = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';

export const TERMINAL_TASK_STATES: ReadonlySet<TaskState> = new Set([
  'completed',
  'failed',
  'cancelled',
]);

export class TaskCancelledError extends Error {
  constructor(readonly taskId: string) {
    super(`Task ${taskId} was cancelled`);
    this.name = 'TaskCancelledError';
  }
}

export interface ITaskHandle<T = unknown> extends IDisposable {
  readonly id: string;
  readonly state: TaskState;
  readonly result: Promise<T>;
  readonly onDidChangeState: Event<TaskState>;
  readonly onDidOutput: Event<string>;
  cancel(): void;
}

export interface IDeferredHandle<T = unknown> extends ITaskHandle<T> {
  resolve(value: T): void;
  reject(reason?: unknown): void;
}

export interface ITaskService {
  readonly _serviceBrand: undefined;

  run<T>(fn: (signal: AbortSignal, output: (data: string) => void) => Promise<T>): ITaskHandle<T>;
  defer<T>(): IDeferredHandle<T>;
}

export const ITaskService: ServiceIdentifier<ITaskService> =
  createDecorator<ITaskService>('taskService');